以下内容源于朱有鹏《物联网大讲堂》课程的学习,如有侵权,请告知删除。
一、概念
(1)竞争状态(简称竟态);
(2)临界段(某一段代码,该代码有可能造成并发,因此应该添加锁。这段代码应该尽可能地短)、互斥锁、死锁(由于互斥锁使用不对,导致的后果);
(3)同步与并发(多CPU、(单cpu下)多任务、中断)。
二、解决竟态的方法
(1)原子操作(automic_t,即不可分割的操作(以前认为原子不可以分割))
- 操作要么不开始,要么开始后就不会被打断。
(2)信号量、互斥锁;
- 程序可以休眠,即当前代码运行条件不满足,因此把cpu交出来,等到条件满足时再使用cpu。
(3)自旋锁;
- 程序不可以休眠,不会让出CPU。这段时间很短,因此可以等待。
- (2)(3)可以“占用篮球场(CPU)与否”的例子来理解。
三、自旋锁和信号量的使用要点
(1)自旋锁不能递归
- 已经拿到自旋锁后,不能再次获取该锁。
(2)自旋锁可以用在中断上下文(即中断处理程序)(信号量不可以,因为当运行条件不满足时,可能造成睡眠),但是在中断上下文中获取自旋锁之前要先禁用本地中断;
- 中断上下文不能使用信号量,因为中断上下文不参与调度,一旦开始就应该执行完,不应该在运行阶段交出cpu。
(3)自旋锁的核心要求
- 拥有自旋锁的代码必须不能睡眠,要一直持有CPU直到释放自旋锁;
(4)
- 信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用,而自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用。
- 如果被保护的共享资源只在进程上下文访问,使用信号量保护该共享资源非常合适;如果对共享资源的访问时间非常短,自旋锁也可以。但是如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),就必须使用自旋锁。
- 自旋锁保持期间是不能被抢占的(所谓抢占,即优先级比其高),而信号量和读写信号量保持期间是可以被抢占的。
- 自旋锁只有在内核可抢占或SMP(多处理器)的情况下才真正需要,在单CPU且不可抢占的内核下,自旋锁的所有操作都是空操作。