Linux内核中9种同步机制

时间:2021-02-19 15:46:45

Linux内核中9种同步机制

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上激活

            或禁止软中断。因为内核有时只需要禁止软中断而不禁止中断。