2021-10-24

10.内核同步方法

原子整数操作

SPARC体系结构是啥??
原子操作就是不可被分割的操作,原子函数只接受一个特殊的数据类型,叫做atomic_c,这种类型可以屏蔽不同体系结构上数据的差异,也可以确保编译器不对相应的值进行访问优化。
内联函数是啥?

10.2 自旋锁

锁的出现是因为原子操作并不能满足在多个复杂函数共享数据的情况下安全。
linux内核主要是自旋锁,它最多只能被一个可执行线程持有,并且征用时,线程不能睡眠,必须进行忙等待。由于从睡眠中唤醒线程会导致开销,所以往往是短期占有锁/禁止睡眠时才需要自旋锁
要在获取锁之前禁止本地中断,因为中断处理程序会试图打断内核进程而陷入忙等待,同时锁持有者又挂起,就陷入了死锁
锁的是数据而不是代码

自旋锁和下半部

同类的tasklet不可能同时运行,同一个处理器上不可能相互抢占;而软中断会在不同处理器上运行,因此需要自旋锁,同一个处理器上软中断不可能被另外的软中断抢占,不需要自旋锁。
大量读者会使写者处于饥饿状态

10.3 读—写自旋锁

又称(共享/排斥锁;并发/排斥锁),锁可被多个读任务持有,一个写任务持有,读任务可以并发

10.4 信号量

信号量:征用信号量的进程会被加入一个睡眠队列。
它适用于锁被长时间使用的情况,短时间持有的锁,中断上下文中都不可用。

计数信号量和二值信号量

计数信号量:可以记录持有者数量,允许任意数量的锁持有者
二值信号量:锁持有者只能是0,1
读—写信号量downgrade_write()方法动态把写锁转换为读锁

10.6 互斥体

相比信号量,优先用mutex
mutex指可睡眠的强制互斥锁,类似于信号量,只是接口更简单。
只能在同一上下文中对它上锁和解锁,不可递归的上锁和解锁,不可被拷贝,手动或重复初始化。

10.9 顺序锁

seq锁 :主要依靠一个序列计数器,写入操作会导致值被增加,读前和读后查看此锁的数据有没有发生变化就能知道读之前和之后有没有被写入过。
当数据存在很多读者,很少写者,希望写者优先于读者,数据很简单时使用。