原子操作 atomic_t

linux内核部件分析(二)——原子性操作atomic_t 在任何处理器平台下,都会有一些原子性操作,供操作系统使用,我们这里只讲x86下面的。在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的。为了弥补这一缺点,x86提供了附加的lock前缀,使带lock前缀的读修改写指令也能原子 阅读详情
1. atomic_t 定义及其原因:
内核定义了atomic_t 数据类型,作为对整数计数器的原子操作的基础。
typedef struct {
	int counter;
} atomic_t;
这里引入了一个特殊的数据类型,而不是直接使用int类型,原因如下:
a. 让原子操作函数只接收 atomic_t 类型的操作数,可以确保原子操作只与这种特殊类型数据一起使用,进而保证了该类型数据不会被传递给其他非原子操作函数。
如果对一个数据,一会采用原子操作,一会又不用原子操作,这没什么好处。
b. 使用 atomic_t 类型确保编译器不对相应的值进行访问优化,这使得原子操作最终接收到正确的内存地址,而不是一个别名。
c. 最后,在不同体系结构上实现原子操作时,使用 atomic_t 可以屏蔽各类体系结构的差异。


原子本意就是不可分割的微粒,所以原子操作就是不可的指令;也就是指在执行过程中不会被别的代码所中断的操作。
各个CPU平台有各自的原子操作实现方式,基本都是通过汇编实现的。

内核提供了两组原子操作接口: 整型原子操作和位原子操作

2. 整型原子操作

整型的原子操作只能对 atomic_t 类型的数据进行处理:

atomic_t v;     //定义 v 原子变量
void atomic_set(atomic_t *v, int i);   //设置原子变量v的值为i

/**
 * atomic_set - set atomic variable
 * @v: pointer of type atomic_t
 * @i: required value
 *
 * Atomically sets the value of @v to @i.
 */
#define atomic_set(v, i) (((v)->counter) = (i))
atomic_t v = ATOMIC_INIT(0);            //定义原子变量v, 并初始化为0

#define ATOMIC_INIT(i)	{ (i) }
atomic_read(atomic_t *v);              //获得原子变量的值,并将 atomic_t 装换位 int 类型的返回值, 应用如下:

printk("%d\n, atomic_read(&v)");   //打印v的值。
atomic_read()定义:

/**
 * atomic_read - read atomic variable
 * @v: pointer of type atomic_t
 *
 * Atomically reads the value of @v.
 */
#define atomic_read(v)	(*(volatile int *)&(v)->counter)

void atomic_add(int i, atomic_t *v);    //原子变量+i
void atomic_sub(int i, atomic_t *v);    //原子变量-i
原子操作最常见的用途是实现计数器,可以用下面两个函数来实现计数器功能:
void atomic_inc(atomic_t *v);           //原子变量+1
void atomic_dec(atomic_t *v);           //原子变量-1
还可以用原子整数操作原子的执行一个操作,并检查结果:
对原子变量执行自增,自减和减操作后(注意没有加),测试其是否为0,为0则返回true,否则返回false

int atomic_inc_and_test(atomic_t *v);
int atomic_dec_and_test(atomic_t *v);
int atomic_sub_and_test(int i, atomic_t *v);
int atomic_add_negative(int i, atomic_t *v); //原子的给 v 加 i, 测试结果是否为负数。如果是负数,返回真;否则返回假。
对原子变量进行加/减,自增/自减操作,并返回新的值。
int atomic_add_return(int i, atomic_t *v);
int atomic_sub_return(int i, atomic_t *v);
int atomic_inc_return(atomic_t *v);
int atomic_sub_return(atomic_t *v);
原子操作通常是内联函数(inline),往往是通过内嵌汇编指令来实现的。

64位整型原子操作:

对于64位的原子操作,使用 atomic64_t 类型,其功能和32位一模一样,使用方法也完全相同,就是把 atomic 变成了 atomic64。

与 atomic_t 一样, atomic64_t 类型其实就是一个多长整型的封装类:

typedef struct {
	long long counter;
} atomic64_t;

3. 位原子操作

位操作函数是对普通的内存地址进行操作的。

它的参数是一个指针和一个位号,第0位是给定地址的最低有效位;32位机上,31位是地址最高有效位;而第32位是下一个字的最低有效位

虽然原子位操作在大多数情况下,是对一个字长的内存进行访问的,因而位号位于0-31(64位机是0-63),但是对位号的范围并没有限制。

void set_bit(nr, void *addr);    //将addr地址的nr位 置为1

void clear_bit(nr, void *addr);  //将addr地址的nr位 清0

void change_bit(nr, void *addr);  //对addr地址的nr位 反置

int test_bit(nr, void *addr);    //返回addr地址的nr位
下面函数是:先原子的设置/清空/翻转 addr 所指地址的第nr位,然后返回原先的值。
int test_and_set_bit(nr, void *addr);
int test_and_clear_bit(nr, void *addr);
int test_and_change_bit(nr, void *addr);

内核还提供两个函数,用来从指定地址开始搜索第一个被置位(或未被置位)的位号:

int find_fist_bit(unsigned long *addr, unsigned int size);

int find_first_zero_bit(unsigned long *addr, unsigned int size);

第一个参数:是个指向内存地址的指针。

第二个参数:是要搜索的总位数。

返回值:是第一个被置位(或未被置位)的位号





linux并发与竞争 对于32位的SOC,在 include/linux/types.h 文件中有一个atomic_t 的结构体相关函数:相应的也提供了 64 位原子变量的操作 API 函数,与32位的 API 函数有用法一样,只是将“atomic_”前缀换为“atomic64_”,将 int 换为 long long。 阅读详情

相关推荐

新手必看!用FFmpeg一键合并ts文件的5种方法(含Windows/Mac终端命令)

本文详细介绍了使用FFmpeg合并TS视频文件的5种实用方法,涵盖Windows和Mac终端命令操作。从基础安装到进阶技巧,包括处理音频不同步、批量处理多个视频等场景,帮助用户轻松将m3u8分片视频合并为完整mp4文件,提升视频处理效率。

weixin_29065959的博客 558

从单片机到Linux内核:一文搞懂原子操作atomic_t的前世今生与实战

本文深入探讨了从单片机到Linux内核开发中原子操作atomic_t的演进与应用。通过对比单片机关中断与Linux原子操作的差异,揭示了多核环境下同步机制的实现原理,并结合实战案例展示了atomic_t在多核LED控制器中的高效应用。文章为开发者提供了从基础到进阶的原子操作指南,助力解决Linux内核开发中的并发难题。

weixin_28731223的博客 249

(篇八)C语言在母串删子串、输入位置截取子串

文章目录一、字符串二、删除指定的字符三、从母串中截取子串四、输入位置截取子串 本篇主要介绍C语言字符串中的相关操作,然后分析两个C语言实例——在母串中指定删除子串、在母串中截取子串 一、字符串 了解C 语言的都知道,C语言中没有字符串类型,所以C语言是用字符串常量、字符指针、字符数组来表示字符串。这些字符串都是以 NULL、’\0’或者ASCII==0来结尾。说白了就是一个个字符组成一串有序序列,...

Viewinfinitely的博客 1512

多线程基础之四:Linux提供的原子锁类型atomic_t

在x86体系下,任何处理器平台下都会有一些原子性操作,在单处理器情况下,单步指令的原子性容易实现。但是在SMP多处理器情况下,只有那些单字的读(将变量读进寄存器)或写(从寄存器写入到变量地址)才是原子性的。故而在SMP下,要保证特定指令集合的原子性即不被中断,x86提供lock前缀用来在执行被lock修饰的指令期间锁住总线,从而实现了“禁止中断”的效果。事实上,Linux操作系统便根据这种针对特殊数

墨篙和小奶猫 2万+

在Ubuntu22.04.2远程服务器上搭建OHIF+Orthanc

在Ubuntu远程服务器上不翻墙,但是本地windows需要科学上网开始之前,首先在终端输入export -p查看是否有代理端口如下如果有就关了,输入如下命令。

weixin_51116549的博客 1335

eNSP-Pro配置又丢了?手把手教你用导出功能防患于未然

本文详细介绍了eNSP-Pro配置防丢失的全套方案,包括运行时内存、虚拟存储设备和宿主机文件系统的配置存储机制,以及多维度备份策略和特殊场景下的恢复技巧。通过优化保存流程、自动化定时导出和版本化管理,帮助网络工程师有效防止配置丢失,提升工作效率。

weixin_42665725的博客 241

atomic 原子操作

修改一个变量会经过读、修改、写的操作序列。但有时该操作序列在执行完毕前会被其他任务或事件打断。比如在多CPU体系结构中,运行在两个CPU上的两个内核控制路径同时并行执行上面操作序列,有可能发生下面的场景:linux专门定义了一种只进行原子操作的类型atomic_t。

lzhf1122的博客 2422

axi ps读写pl_PL读写DDR:Datamover能干什么

最近发现工程项目中一直在用AXI-DMA。这玩意儿搬数据倒是没问题,就是用axi-lite配置起来非常反人类。。。简单的办法其实是用datamover ip核。这个ip核能干嘛呢。准备写个文章解析一下。由于好多feature没用过,所以仅仅看文档可能理解有误,欢迎指出错误。首先扫个盲:MM2S指的是Memory map to stream. 读DDR. S2MM指的是steam to memory...

weixin_35908791的博客 1597

linux 原子性操作atomic_t

在任何处理器平台下,都会有一些原子性操作,供操作系统使用,我们这里只讲x86下面的。在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的。为了弥补这一缺点,x86提供了附加的lock前缀,使带lock前缀的读修改写指令也能原子性执行。带lock前缀的指令在操作时会锁住总线,使自身的执行即使在多处理器间也是原子性执行的。xchg指令不带lock前

晴天的专栏 5225

25届电信保研经验贴(空天院)

学校:中九专业:电子信息工程加权:92.89绩点:3.91/4.0rank:前五学期rank2/95,综合排名rank1(前六学期和综合排名出的晚,实际上只用到了前五学期)科研竞赛:市级大创、数模省一、数竞省二,其他校奖若干英语:六级462、四级548个人感觉:rank=科研>竞赛>英语总之rank和科研必须得有一项,要么就rank高,很多强com院校入营看rank。我rank比较有优势,因此报的多是强com院校。要么就科研经历丰富,多主动联系老师,特别是弱com院校。冬令营:空天院。

qq_68608661的博客 6337

基于STM32F334C8T6的四开关Buck-Boost双向DC-DC电源设计与实现(附源码、仿真与计算书)

本文详细介绍了基于STM32F334C8T6的四开关Buck-Boost双向DC-DC电源设计方案。该设计利用STM32的高分辨率定时器(HRTIM)实现精确PWM控制,支持Buck、Boost和Buck-Boost三种工作模式自动切换,具备双向能量流动能力。通过PSIM仿真和Mathcad计算书进行参数优化,实测效率达95.8%,适用于新能源系统和电池管理等场景。

www00的博客 525

Linux内核之原子操作atomic_t用法实例(三十九)

本篇目的:Linux内核之atomic_t用法实例Linux内核中的atomic_t是一个原子操作的计数器类型,它被广泛用于多线程环境中,确保对计数器的操作是线程安全的。在Linux内核中,许多场合需要对某些值进行原子操作,例如,进程计数、互斥锁的计数器等。atomic_t提供了对这些值进行增加、减少和获取当前值的原子操作,避免了在多线程环境中由于竞态条件引起的并发问题。atomic_t的定义在头文件中,它是一个简单的整数类型(通常是32位),并提供了以下几个主要的操作函数::初始化一个。

Android系统攻城狮 2849

LOFIC / 全局快门在移动端的可行性:曝光容限、读出噪声与算力预算

手机端引入 LOFIC 与全局快门的核心权衡在于:在有限像素面积与功耗下,如何换取更高的动态范围与运动场景鲁棒性。LOFIC 通过侧向溢流到积分电容扩大满井并保持较高转换增益,全局快门在帧内一次性采样消除行时序伪影,但需付出像素填充率、读出噪声与片上存储功耗的代价。本文以工程可实操为目标,给出像素与读出链的简化模型、曝光损益测算、数据率与带宽估算、端到端算力与热预算方法,配套寄存器配置流程、帧内/帧间切换策略与验证清单,帮助在真实移动 SoC 与 ISP 约束下完成可行性评估与原型落地。

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1140

atomic_t原子变量操作

原子类型参数定义的典型使用场景便是多进程中共享资源的计数加减,如信号量semaphores中的资源总数便是经典的使用场景。所以atomic_t原子锁支持的便是声明了一个具有原子操作特性的整数。 typedef struct{ volatile int counter; //volatile修饰符高速gcc不要对该类型数据进行优化处理,即对它的访问都是对 //内存的访问,而不是对寄存器的访问。即要读,必须重新找个寄存器载入该参数,而不是直接利用该参数 //此刻

qq_35399548的博客 373

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

原子性操作atomic_t

内核定义了atomic_t 数据类型,作为对整数计数器的原子操作的基础。 各个CPU平台有各自的原子操作实现方式,基本都是通过汇编实现的。  原子操作 原子操作是Linux中提供的一种实现同步的方法,所谓原子操作是指某一操作在执行过程中是不可以被打断的,它要么全部执行完毕,要么就一点也不执行。也就是说原子操作是绝对不会出现该操作执行了一半,内核又去执行其他操作的情况。 原子操作分为原子位

被遗忘的前辈 1万+

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Linux(内核剖析):29---内核同步之(原子操作(原子整数操作(atomic_t、atomic64_t)、原子位操作))

一、原子操作概述 原子操作可以保证指令以原子的方式执行——执行过程不被打断。众所周知,原子原本指的是不可分割的微粒,所以原子操作也就是不能够被分割的指令 Linux内核提供的原子接口 内核提供了两组原子操作接口——一组针对整数进行操作,另一组针对单独的位进行操作 在Linux支持的所有体系结构上都实现了这两组接口。大多数体系结构会提供支持原子操作的简单算术指令。而有些体系结构确实缺少简单的...

董哥的黑板报 7203

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Linux内核部件分析 ——原子性操作atomic_t

在任何处理器平台下,都会有一些原子性操作,供操作系统使用,我们这里只讲x86下面的。在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的。为了弥补这一缺点,x86提供了附加的lock前缀,使带lock前缀的读修改写指令也能原子性执行。带lock前缀的指令在操作时会锁住总线,使自身的执行即使在多处理器间也是原子性执行的。xchg指令不带lock前

jw903的专栏 1187

Linux内核部件分析——原子性操作atomic_t

Linux内核部件分析 原子性操作atomic_t [日期:2011-10-06] 来源:Linux社区  作者:qb_2008 [字体:大 中 小] 在任何处理器平台下,都会有一些原子性操作,供操作系统使用,我们这里只讲x86下面的。在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的。为

zdy0_2004的专栏 682

转-原子操作atomic_t

  所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。   原子操作需要硬件的支持,因此是架构相关的,其API和原子类型的定义都定义在内核源码树的include/asm/atomic.h文件中,它们都使用汇编语言实现,因为C语言并不能实现这样的操作。 ...

dgpqzwx2597的博客 133

Linux内核部件分析--原子性操作atomic_t

在任何处理器平台下,都会有一些原子性操作,供操作系统使用,我们这里只讲x86下面的。在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的。为了弥补这一缺点,x86提供了附加的lock前缀,使带lock前缀的读修改写指令也能原子性执行。带lock前缀的指令在操作时会锁住总线,使自身的执行即使在多处理器间也是原子性执行的。xchg指令不带lock前

myxmu的专栏 980

atomic_t原子操作

所谓原子操作,就是该操作绝不会在执行完毕前被任何其他任务或事件打断,也就说,它的最小的执行单位,不可能有比它更小的执行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。  原子操作需要硬件的支持,因此是架构相关的,其API和原子类型的定义都定义在内核源码树的include/asm/atomic.h文件中,它们都使用汇编语言实现,因为C语言并不能实现这样的操作。  原子操作主要用于...

a623277405的博客 359

linux内核设备驱动模型一之原子性操作atomic_t

在任何处理器平台下,都会有一些原子性操作,供操作系统使用,我们这里只讲x86下面的。在单处理器情况下,每条指令的执行都是原子性的,但在多处理器情况下,只有那些单独的读操作或写操作才是原子性的。为了弥补这一缺点,x86提供了附加的lock前缀,使带lock前缀的读修改写指令也能原子性执行。带lock前缀的指令在操作时会锁住总线,使自身的执行即使在多处理器间也是原子性执行的。xchg指令不带lock前

Jkf40622的专栏 819
上一篇: 队列 -- fifo
下一篇: 自旋锁_读写自旋锁_顺序锁_读-拷贝-更新
lamdoc
博客等级 码龄18年 155粉丝 655原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值