内核并发方法
1.中断屏蔽
(1)释义:中断屏蔽为单CPU中实现的并发方式,因为CPU在执行多线程和多进程的时候是通过时间片的时间来进行的切换由于速度极快所以在人眼看起来是同时执行,所以我们在需要在访问共享资源的时候我们需要在执行的时候DISABLE,执行完之后ENABLE。
(2)用法:
local_irq_disable()/*屏蔽中断*/
...
critical section/*临界区*/
...
local_irq_enable()/*打开中断*/
(3)注意:
local_irq_ disable()和local_irq_ engble()都只能禁止和使能本CPU内的中断,因此,并不能解决SMP多CPU引发的竞态
2.原子操作
(1)释义:原子操作就是指计算机中最小的执行语句,指CPU必须执行完,无法被打断的执行命令,分别原子操作的方法就是观察该条命令是否为一条机器码完成的操作,我们可以使用objdump反汇编命令来查看该命令是否为原子操作,具体则是是使用
arm-linux-objdump -Sl a.out
(2)用法:
实现方法参见include/asm/atomic.h
整型原子操作
设置原子变量的值
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,否则返回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);
上述操作对原子变量进行加/减和自增/自减操作,并返回新的值
3.自旋锁
(1)释义:和互斥锁作用一样,都是为了为资源加锁,防止共享资源被随意篡改,但是和互斥锁的最大不同在于,自旋锁在没有得到资源使用权的时候会一直占用CPU,直到资源被释放,互斥锁则当没有资源的时候会进入睡眠状态,让出CPU的使用权,自旋锁的常常被内核使用,原因在于自旋锁能够有效地提高内核的性能。
(2)用法:
定义自旋锁
spinlock_t lock;
初始化自旋锁
spin_ lock_ init(&lock)
获得自旋锁
spin_lock(&lock)
如果能够立即获得锁,它就马上返回,否则,它将自旋在那里
spin_ trylock(&lock)
该宏尝试获得自旋锁lock, 如果能立即获得锁,它获得锁并返回真,否则立即返回假
释放自旋锁
spin_unlock(&lock)
防止中断和底半部的影响
spin_ lock_ irq() = spin_lock()+ local_irq_disable()
spin_ unlock_ irq() = spin_ unlock() + local _irq_enable()
spin_ lock_ irqsave() = spin_ lock() + local _irq_save()
spin_ unlock_ irqrestore() = spin_ unlock() + local_irq_ restore()
spin_ lock_ bh() = spin_ lock() + local_bh_ disable()
spin_ unlock _bh() = spin_ unlock() + local_bh_ enable()