标签:
所谓原子操作,就是该操作绝不会在运行完成前被不论什么其它任务或事件打断,也就说。它的最小的运行单位,不可能有比它更小的运行单位,因此这里的原子实际是使用了物理学里的物质微粒的概念。
原子操作须要硬件的支持,因此是架构相关的。其API和原子类型的定义都定义在内核源代码树的include/asm/atomic.h文件里,它们都使用汇编语言实现,由于C语言并不能实现这种操作。
原子操作主要用于实现资源计数。非常多引用计数(refcnt)就是通过原子操作实现的。原子类型定义例如以下:
typedef struct { volatile int counter; } atomic_t; |
volatile修饰字段告诉gcc不要对该类型的数据做优化处理,对它的訪问都是对内存的訪问,而不是对寄存器的訪问。
原子操作API包含:
atomic_read(atomic_t * v); |
该函数对原子类型的变量进行原子读操作。它返回原子类型的变量v的值。
atomic_set(atomic_t * v, int i); |
该函数设置原子类型的变量v的值为i。
void atomic_add(int i, atomic_t *v); |
该函数给原子类型的变量v添加值i。
atomic_sub(int i, atomic_t *v); |
该函数从原子类型的变量v中减去i。
int atomic_sub_and_test(int i, atomic_t *v); |
该函数从原子类型的变量v中减去i,并推断结果是否为0,假设为0。返回真,否则返回假。
void atomic_inc(atomic_t *v); |
该函数对原子类型变量v原子地添加1。
void atomic_dec(atomic_t *v); |
该函数对原子类型的变量v原子地减1。
int atomic_dec_and_test(atomic_t *v); |
该函数对原子类型的变量v原子地减1。并推断结果是否为0,假设为0,返回真。否则返回假。
int atomic_inc_and_test(atomic_t *v); |
该函数对原子类型的变量v原子地添加1。并推断结果是否为0,假设为0。返回真,否则返回假。
int atomic_add_negative(int i, atomic_t *v); |
该函数对原子类型的变量v原子地添加I。并推断结果是否为负数。假设是,返回真。否则返回假。
int atomic_add_return(int i, atomic_t *v); |
该函数对原子类型的变量v原子地添加i,而且返回指向v的指针。
int atomic_sub_return(int i, atomic_t *v); |
该函数从原子类型的变量v中减去i,而且返回指向v的指针。
int atomic_inc_return(atomic_t * v); |
该函数对原子类型的变量v原子地添加1而且返回指向v的指针。
int atomic_dec_return(atomic_t * v); |
该函数对原子类型的变量v原子地减1而且返回指向v的指针。
原子操作通经常使用于实现资源的引用计数,在TCP/IP协议栈的IP碎片处理中。就使用了引用计数,碎片队列结构struct ipq描写叙述了一个IP碎片。字段refcnt就是引用计数器,它的类型为atomic_t。当创建IP碎片时(在函数ip_frag_create中)。使用atomic_set函数把它设置为1。当引用该IP碎片时,就使用函数atomic_inc把引用计数加1。
当不须要引用该IP碎片时,就使用函数ipq_put来释放该IP碎片,ipq_put使用函数atomic_dec_and_test把引用计数减1并推断引用计数是否为0,假设是就释放IP碎片。
函数ipq_kill把IP碎片从ipq队列中删除。并把该删除的IP碎片的引用计数减1(通过使用函数atomic_dec实现)。
原子操作仅运行一次。在运行过程中不会中断也不会休眠;是最小的运行单元。鉴于原子操作这些特性。能够利用它来解决竞态问题。
往后其它同步机制都是在原子操作的基础上进行扩展的。
原子操作有整型原子操作、64位原子操作以及位原子操作。
1 整型原子操作(Atomic Integer Operations)
要使用原子操作,须要定义一个原子变量,然后使用内核提供的接口对其进行原子操作。
整型原子变量结构例如以下
版权声明:本文博主原创文章。博客,未经同意不得转载。
标签:
原文地址:http://www.cnblogs.com/bhlsheji/p/4877072.html