1. 中断屏蔽:1.1 说明:在单 CPU 范围内避免竞态的简单而省事的方法是在进入临界区之前屏蔽系统的中断优点是:当中断屏蔽的时候,内核抢占进程之间的并发也得以避免了缺点是:由于linux的异步I/O、进程调度等很多重要操作都依赖于中断,这些功能在中断屏蔽期间将不能使用。当长时间的屏蔽中断,有可能导致数据的丢失甚至系统的崩溃。
1.2 使用local_irq_disable()
local_irq_enable()
两者配合只能禁止和使能本 CPU 内的中断,这就是说,在解决 SMP 多 CPU 引起的竞态的情况是无能为力的,在这种情况下适宜与自旋锁联合使用。
local_irq_save(flag)
local_irq_restore(flag)
禁止中断,保存目前的 CPU 的中断位信息。
local_bh_disable()
locla_bh_enable()
只是禁止中断的底半部
2. 原子操作:原子操作指的是在执行过程中不会被别的代码路径所中断的操作。
或者 “可被中断的一个或一系列操作”
原子操作分为两类:整型原子操作、位原子操作
2.1 整型原子操作:设置原子变量的值:
void atomic_set(atomic_t *v, int i); /* 设置原子变量的值为 i */
atomic_t v = ATOMIC_INIT(0); /* 定义原子变量 v ,初始化为0 */
获取原子变量的值:
atomic_read(atomic_t *v); /* 返回原子变量的值 */
加/减:
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 */
操作并测试:
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,
0,true
!0,false
操作并返回:
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);
执行完操作后,返回新的值
2.2 位原子操作:置位: -- 置1
void set_bit(nr, void *addr);
功能:
将 addr 地址的第 nr 位置为 1
清零:
void clear_bit(nr, void *addr);
位翻转:
void change_bit(nr, void *addr);
测试:
test_bit(nr, void *addr);
功能:
返回 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);
功能:
相当于先执行了test_bit(nr, void *addr)后再执行 xxx_bit(nr, void *addr) |