同步:我等你用完厕所,我再用。
互斥:我正在用厕所,你不能进来。
同步与互斥经常一起讨论,因为互斥操作可以通过同步实现。举例来说,同事A先写完报表,经理B才能拿去汇报,B等待A完成的过程是同步。A使用会议室时,B也想使用,但必须等待,这就是互斥。经理B等A用完提醒他,这就是用同步实现互斥。
只有一个人能同时使用的资源称为临界资源。任务A、B使用同一个串口打印时,如果同时进行,会混杂,所以需要A用完B再用,这就是互斥的实现。
假设在一家公司里,只有一台3D打印机,两个员工A和B都需要使用这台打印机来打印他们的设计。
在这个过程中,打印机是临界资源。我们使用了“等待-通知”的同步机制来实现对打印机的互斥访问。
之前用flag
来控制同步和互斥,虽然简单,但不可靠。我们可以使用信号量来替代flag
。信号量能更好地管理任务间的同步,确保资源的互斥访问。例如,使用二值信号量来确保打印机一次只能被一个任务使用,当一个任务完成打印后,信号量通知下一个任务可以开始。
正确性
效率:等待者要进入阻塞状态
多种解决方案
能实现同步、互斥的内核方法有:任务通知(task notification)
、队列(queue)
、事件组(event group)
、 信号量(semaphoe)
、互斥量(mutex)
。
1. 信号量(Semaphore)
2. 互斥量(Mutex)
3. 事件(Event)
4. 条件变量(Condition Variable)
5. 记忆技巧
内核对 象 | 生产者 | 消费 者 | 数据/状态 | 说明 |
---|---|---|---|---|
队列 | ALL | ALL | 数据:若干个数据 谁都可以往队列里扔数据, 谁都可以从队列里读数据 | 用来传递数据, 发送者、接收者无限制, 一个数据只能唤醒一个接 收者 |
事件组 | ALL | ALL | 多个位:或、与 谁都可以设置(生产)多个位, 谁都可以等待某个位、若干 个位 | 用来传递事件, 可以是N个事件, 发送者、接受者无限制, 可以唤醒多个接收者:像 广播 |
信号量 | ALL | ALL | 数量:0~n 谁都可以增加一个数量, 谁都可消耗一个数量 | 用来维持资源的个数, 生产者、消费者无限制, 1个资源只能唤醒1个接收 者 |
任务通 知 | ALL | 只有 我 | 数据、状态都可以传输, 使用任务通知时, 必须指定接受者 | N对1的关系: 发送者无限制, 接收者只能是这个任务 |
互斥量 | 只能A开 锁 | 只能A开 锁 | 位:0、1 我上锁:1变为0, 只能由我开锁:0变为1 | 就像一个空厕所, 谁使用谁上锁, 也只能由他开锁 |
使用图形对比如下:
(ISR)
都可以使用。(TCB)
中的数值。