linux 原子变量

有时, 一个共享资源是一个简单的整数值. 假设你的驱动维护一个共享变量 n_op, 它告 知有多少设备操做目前未完成. 正常地, 即使一个简单的操做例如:ide

 

n_op++;函数

 

可能须要加锁. 某些处理器可能以原子的方式进行那种递减, 可是你不能依赖它. 可是一 个完整的加锁体制对于一个简单的整数值看来过度了. 对于这样的状况, 内核提供了一个 原子整数类型称为 atomic_t, 定义在 <asm/atomic.h>.测试

 

一个 atomic_t 持有一个 int 值在全部支持的体系上. 可是, 由于这个类型在某些处理 器上的工做方式, 整个整数范围可能不是均可用的; 所以, 你不该当期望一个 atomic_tatom

 

持有多于 24 位. 下面的操做为这个类型定义而且保证对于一个 SMP 计算机的全部处理 器来讲是原子的. 操做是很是快的, 由于它们在任何可能时编译成一条单个机器指令.资源

 

void atomic_set(atomic_t *v, int i); atomic_t v = ATOMIC_INIT(0);it

 

设置原子变量 v 为整数值 i. 你也可在编译时使用宏定义 ATOMIC_INIT 初始化原 子值.asm

 

int atomic_read(atomic_t *v); 返回 v 的当前值.编译

void atomic_add(int i, atomic_t *v);class

 

由 v 指向的原子变量加 i. 返回值是 void, 由于有一个额外的开销来返回新值, 而且大部分时间不须要知道它.test

 

void atomic_sub(int i, atomic_t *v); 从 *v 减去 i.void atomic_inc(atomic_t *v); void atomic_dec(atomic_t *v);

 

递增或递减一个原子变量.

 

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);

 

进行一个特定的操做而且测试结果; 若是, 在操做后, 原子值是 0, 那么返回值是 真; 不然, 它是假. 注意没有 atomic_add_and_test.

 

int atomic_add_negative(int i, atomic_t *v);

加整数变量 i 到 v. 若是结果是负值返回值是真, 不然为假. 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_dec_return(atomic_t *v);

 

就像 atomic_add 和其相似函数, 除了它们返回原子变量的新值给调用者.

 

如同它们说过的, atomic_t 数据项必须经过这些函数存取. 若是你传递一个原子项给一 个指望一个整数参数的函数, 你会获得一个编译错误.

 

你还应当记住, atomic_t 值只在当被置疑的量真正是原子的时候才起做用. 须要多个 atomic_t 变量的操做仍然须要某种其余种类的加锁. 考虑一下下面的代码:

 

atomic_sub(amount, &first_atomic); atomic_add(amount, &second_atomic);

 

从第一个原子值中减去 amount, 可是尚未加到第二个时, 存在一段时间. 若是事情的 这个状态可能产生麻烦给可能在这 2 个操做之间运行的代码, 某种加锁必须采用.

相关文章
相关标签/搜索