1)每CPU变量
主要形式是数据结构的数组,系统中的每个CPU对应数组的一个元素。
使用情况:数据应在逻辑上是独立的
使用原则:应在内核控制路径禁用抢占的情况下访问每CPU变量。
2)原子操作
原理:是借助于汇编语言指令中对“读--修改--写”具有原子性的汇编指令来实现。
3)内存屏障
原理:使用内存屏障原语确保在原语之后的操作开始之前,原语之前的操作已经完成。
------------------------------------------------------------------------------------------------------------------------------------
4)自旋锁
主要用于多处理器环境中。
原理:如果一个内核控制路径发现所请求的自旋锁已经由运行在另一个CPU上的内核控制
路径“锁着”,就反复执行一条循环指令,直到锁被释放。
说明:自旋锁一般用于保护禁止内核抢占的临界区。
在单处理器上,自旋锁的作用仅是禁止或启用内核抢占功能。
5)顺序锁:
顺序锁与自旋锁非常相似,仅有一点不同,即顺序锁中的写者比读者有较高的优先级,也就
意味着即使读者正在读的时候也允许写者继续运行。
------------------------------------------------------------------------------------------------------------------------------------
6)RCU
主要用于保护被多个CPU读的数据结构。
允许多个读者和写者同时运行,且RCU是不用锁的。
使用限制:
1)RCU只保护被动态分配并通过指针引用的数据结构
2)在被RCU保护的临界区中,任何内核控制路径都不能睡眠。
原理:
当写者要更新数据时,它通过引用指针来复制整个数据结构的副本,然后对这个副本进行
修改。修改完毕后,写者改变指向原数据结构的指针,使它指向被修改后的副本,(指针
的修改是原子的)。
7)信号量:
原理: 当内核控制路径试图获取内核信号量所保护的忙资源时,相应的进程被挂起;只有在
资源被释放时,进程才再次变为可运行。
使用限制:只有可以睡眠的函数才能获取内核信号量 ;
中断处理程序和可延迟函数都不能使用内核信号量。
8)本地中断禁止
原理:本地中断禁止可以保证即使硬件设备产生了一个IRQ信号时,内核控制路径也会继续运行,
从而使中断处理例程访问的数据结构受到保护。
不足:禁止本地中断并不能限制运行在另一个CPU上的中断处理程序对共享数据结构的并发访问,
故在多处理器环境中,禁止本地中断需要与自旋锁一起使用。
9)本地软中断的禁止
- 方法1:
由于软中断是在硬件中断处理程序结束时开始运行的,所以最简单的方式是禁止那个CPU上的中断。
因为没有中断处理例程被激活,故软中断就没有机会运行。
- 方法2:
通过操纵当前thread_info描述符preempt_count字段中存放的软中断计数器,可以在本地CPU上激活
或禁止软中断。因为内核有时只需要禁止软中断而不禁止中断。