atomic_t 类型在进行整数算术时是不错的. 可是, 它没法工做的好, 当你须要以原子方 式操做单个位时. 为此, 内核提供了一套函数来原子地修改或测试单个位. 由于整个操做 在单步内发生, 没有中断(或者其余处理器)能干扰.ide
原子位操做很是快, 由于它们使用单个机器指令来进行操做, 而在任什么时候候低层平台作的 时候不用禁止中断. 函数是体系依赖的而且在 <asm/bitops.h> 中声明. 它们保证是原子 的, 即使在 SMP 计算机上, 而且对于跨处理器保持一致是有用的.函数
不幸的是, 键入这些函数中的数据也是体系依赖的. nr 参数(描述要操做哪一个位)经常定 义为 int, 可是在几个体系中是 unsigned long. 要修改的地址经常是一个 unsigned long 指针, 可是几个体系使用 void * 代替.测试
各类位操做是:atom
void set_bit(nr, void *addr);指针
设置第 nr 位在 addr 指向的数据项中. void clear_bit(nr, void *addr);调试
清除指定位在 addr 处的无符号长型数据. 它的语义与 set_bit 的相反. void change_bit(nr, void *addr);源码
翻转这个位. test_bit(nr, void *addr);it
这个函数是惟一一个不须要是原子的位操做; 它简单地返回这个位的当前值.asm
int test_and_set_bit(nr, void *addr); int test_and_clear_bit(nr, void *addr); int test_and_change_bit(nr, void *addr);class
原子地动做如同前面列出的, 除了它们还返回这个位之前的值.
当这些函数用来存取和修改一个共享的标志, 除了调用它们不用作任何事; 它们以原子发 生进行它们的操做. 使用位操做来管理一个控制存取一个共享变量的锁变量, 另外一方面, 是有点复杂而且应该有个例子. 大部分现代的代码不以这种方法来使用位操做, 可是象下 面的代码仍然在内核中存在.
一段须要存取一个共享数据项的代码试图原子地请求一个锁, 使用 test_and_set_bit 或 者 test_and_clear_bit. 一般的实现展现在这里; 它假定锁是在地址 addr 的 nr 位. 它还假定当锁空闲是这个位是 0, 忙为 非零.
/* try to set lock */
while (test_and_set_bit(nr, addr) != 0) wait_for_a_while();
/* do your work */
/* release lock, and check... */
if (test_and_clear_bit(nr, addr) == 0) something_went_wrong(); /* already released: error */
若是你通读内核源码, 你会发现象这个例子的代码. 可是, 最好在新代码中使用自旋锁; 自旋锁很好地调试过, 它们处理问题如同中断和内核抢占, 而且别人读你代码时没必要努力 理解你在作什么.