一、自旋锁
Linux 内核使用结构体 spinlock_t 表示自旋锁。
1. 定义:自旋锁最多只能被一个内核任务持有,如果一个内核任务试图请求一个已经被持有的自旋锁,那么这个任务就会一直进行忙循环——旋转——等待锁重新可用。
2. 作用:自旋锁可以在任何时刻防止多于一个的内核任务同时进入临界区,因此这种锁可有效地避免多处理器上并发运行的内核任务竞争共享资源。
3. 自旋锁的初衷:在短期间内进行轻量级的锁定。因为等待锁重新可用的期间进行自旋(特别浪费处理器时间)!
4. 注意:
1.自旋锁不允许任务睡眠,它能够在中断上下文中使用。
当线程 A得到锁以后会暂时禁止内核抢占(自旋锁会自动禁止抢占)。如果线程 A 在持有锁期间进入了休眠状态,那么线程 A 会自动放弃 CPU 使用权。线程 B 开始运行,线程 B 也想要获取锁,但是此时锁被 A 线程持有,而且内核抢占还被禁止了!线程 B 无法被调度出去,那么线程 A 就无法运行,锁也就无法释放,好了,死锁发生了!
2.在中断里面使用自旋锁的时候,在获取锁之前一定要先禁止本地中断。
线程 A 先运行,并且获取到了 lock 这个锁,当线程 A 运行 functionA 函数的时候中断发生了,中断抢走了 CPU 使用权。右边的中断服务函数也要获取 lock 这个锁,但是这个锁被线程 A 占有着,中断就会一直自旋,等待锁有效。但是在中断服务函数执行完之前,线程 A 是不可能执行的,线程 A 说“你先放手”,中断说“你先放手”,场面就这么僵持着,死锁发生!
二、信号量(睡眠锁)
Linux 内核使用 semaphore 结构体表示信号量。
1. 定义:信号量通常是一个整数变量,用于记录某个共享资源的可用数量,它可以被多个线程或进程同时访问和修改。(信号量本质是一个计数器)
2. 主要作用:它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
3. 实例:比如,有100个停车位的停车场,门口电子显示屏上实时更新的停车数量就是一个信号 量。这个停车的数量就是一个信号量,他告诉我们是否可以停车进去。当有车开进去,信号量加一,当 有车开出来,信号量减一。
三、自旋锁和信号量的区别
1. 自旋锁只能用于互斥,信号量可用于互斥或作为计数信号量。
2. 自旋锁在任何给定时间只允许一个进程访问临界区。信号量允许在任何给定时间有多个进程访问临界区。
3. 自旋锁是一个忙等待过程,不会引起调用者睡眠,仅允许短时间被持有。 相比之下,信号量是一个睡眠等待过程,会引起调用者睡眠,适用于锁被长时间持有的情况。。
信号量的概念比锁的范围更大, 可以说, 锁是信号量的一种特殊情况。
一般来说,自旋锁只在进程内有效,而信号量可同于控制多个进程之间的同步。
但是,无论是信号量(互斥),还是自旋锁,在任何时刻,最多只能有一个保持者,即在任何时刻最多只能有一个执行单元获得锁。这就是它们的"类似"。
四、自旋锁和信号量在互斥使用时需要注意哪些?
使用自旋锁的进程不能睡眠,使用信号量的进程可以睡眠。文章来源:https://www.toymoban.com/news/detail-483289.html
五、在中断服务程序里面的互斥是使用自旋锁还是信号量?还是两者都能用?为什么?
自旋锁,因为自旋锁不会导致阻或者睡眠。文章来源地址https://www.toymoban.com/news/detail-483289.html
到了这里,关于【001 基础知识】自旋锁、信号量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!