Linux自旋锁原理?

Linux自旋锁原理?,第1张

自旋锁(Spin Lock)是一种典型的对临界资源进行互斥访问的手段,其名称来源于它的工作方式。为了获得一个自旋锁,在某CPU上运行的代码需先执行一个原子 *** 作,该 *** 作测试并设置(Test-AndSet)某个内存变量。由于它是原子 *** 作,所以在该 *** 作完成之前其他执行单元不可能访问这个内存变量。如果测试结果表明锁已经空闲,则程序获得这个自旋锁并继续执行;如果测试结果表明锁仍被占用,程序将在一个小的循环内重复这个“测试并设置” *** 作,即进行所谓的“自旋”,通俗地说就是“在原地打转”。当自旋锁的持有者通过重置该变量释放这个自旋锁后,某个等待的“测试并设置” *** 作向其调用者报告锁已释放。理解自旋锁最简单的方法是把它作为一个变量看待,该变量把一个临界区标记为“我当前在运行,请稍等一会”或者标记为“我当前不在运行,可以被使用。如果A执行单元首先进入例程,它将持有自旋锁;当B执行单元试图进入同一个例程时,将获知自旋锁已被持有,需等到A执行单元释放后才能进入。在ARM体系结构下,自旋锁的实现借用了ldrex指令、strex指令、ARM处理器内存屏障指令dmb和dsb、wfe指令和sev指令,这类似于代码清单7.1的逻辑。可以说既要保证排他性,也要处理好内存屏障。自旋锁主要针对SMP或单CPU但内核可抢占的情况,对于单CPU和内核不支持抢占的系统,自旋锁退化为空 *** 作。在单CPU和内核可抢占的系统中,自旋锁持有期间中内核的抢占将被禁止。由于内核可抢占的单CPU系统的行为实际上很类似于SMP系统,因此,在这样的单CPU系统中使用自旋锁仍十分必要。另外,在多核SMP的情况下,任何一个核拿到了自旋锁,该核上的抢占调度也暂时禁止了,但是没有禁止另外一个核的抢占调度。尽管用了自旋锁可以保证临界区不受别的CPU和本CPU内的抢占进程打扰,但是得到锁的代码路径在执行临界区的时候,还可能受到中断和底半部的影响。为了防止这种影响,就需要用到自旋锁的衍生。

既然是对一个变量进行保护,当然是一个自旋锁了,还没见过一个变量能当两个用的。

我觉得你对这段代码的理解有问题,用 spin_lock 和 spin_unlock 的目的是保证程序在对 xxx_lock 进行 *** 作的时候,不会有其它进程改变这个值,是为了保证数据的准确性。

你可以设想一下,如果没有自旋锁,代码运行起来会有什么问题。假设 A,B两个进程同时访问 open , 没有使用自旋锁,此时 xxx_lock=0, A 进程在判断 if (xxx_count) 时,会认为设备没有被使用,那么它会继续后面的 xxx_count++ *** 作,但假如这时 CPU 切换进程, A 进程还没有来得及把 xxx_count 变成 1 的时候, B 进程开始运行,那么 B 进程此时也会认为设备没有被使用,它也会进行后继 *** 作,这样就会出现两个进程同时访问设备的错误。

open 和 release 当然可以同时访问,只不过在运行 spin_lock 的时候,后访问的进程会被阻塞而已。假设有 A 进程访问 open ,B 进程访问 release ,你可以把这种情况理解为 A , B 进程同时访问 open 函数,这样或许能更好的理解这段代码。因为 open 和 release 在使用自旋锁的时候,方法是一样的。

spin_lock 和 CPU 系统无关,不管是单 CPU 还是多 CPU ,运行结果都是一样的。

这个逻辑关系比较难解释,不知道你看懂我的意思没。

从最初的原子 *** 作,到后来的信号量,从大内核锁到今天的自旋锁。这些同步机制的发展伴随Linux从单处理器到对称多处理器的过渡;

伴随着从非抢占内核到抢占内核的过度。Linux的锁机制越来越有效,也越来越复杂。

Linux的内核锁主要是自旋锁和信号量。

自旋锁最多只能被一个可执行线程持有,如果一个执行线程试图请求一个已被争用(已经被持有)的自旋锁,那么这个线程就会一直进行忙循环——旋转——等待锁重新可用。要是锁未被争用,请求它的执行线程便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个的执行线程同时进入临界区。

Linux中的信号量是一种睡眠锁。如果有一个任务试图获得一个已被持有的信号量时,信号量会将其推入等待队列,然后让其睡眠。这时处理器获得自由去执行其它代码。当持有信号量的进程将信号量释放后,在等待队列中的一个任务将被唤醒,从而便可以获得这个信号量。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/yw/8791390.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-21
下一篇2023-04-21

发表评论

登录后才能评论

评论列表(0条)

    保存