您的当前位置:首页正文

10、FreeRTOS 同步和互斥

2024-12-02 来源:个人技术集锦

一、同步和互斥的概念

1.1 简单理解

同步:我等你用完厕所,我再用。
互斥:我正在用厕所,你不能进来。

1.2 同步与互斥

同步与互斥经常一起讨论,因为互斥操作可以通过同步实现。举例来说,同事A先写完报表,经理B才能拿去汇报,B等待A完成的过程是同步。A使用会议室时,B也想使用,但必须等待,这就是互斥。经理B等A用完提醒他,这就是用同步实现互斥。

1.3 临界资源

只有一个人能同时使用的资源称为临界资源。任务A、B使用同一个串口打印时,如果同时进行,会混杂,所以需要A用完B再用,这就是互斥的实现。

1.4 新的实例

假设在一家公司里,只有一台3D打印机,两个员工A和B都需要使用这台打印机来打印他们的设计。

  • 同步:员工A先将设计文件发送到打印机并开始打印。员工B不能立即开始打印,他必须等待A的打印任务完成。这就是同步,B在等待A的任务完成。
  • 互斥:打印机一次只能处理一个打印任务。这意味着当A在使用打印机时,B不能使用。这就是互斥,A和B互斥地访问打印机这个资源。

在这个过程中,打印机是临界资源。我们使用了“等待-通知”的同步机制来实现对打印机的互斥访问。

1.5 改进实现

之前用flag来控制同步和互斥,虽然简单,但不可靠。我们可以使用信号量来替代flag。信号量能更好地管理任务间的同步,确保资源的互斥访问。例如,使用二值信号量来确保打印机一次只能被一个任务使用,当一个任务完成打印后,信号量通知下一个任务可以开始。

二、FreeRTOS的解决方案

  • 正确性

  • 效率:等待者要进入阻塞状态

  • 多种解决方案

三、各类方法对比

能实现同步、互斥的内核方法有:任务通知(task notification)队列(queue)事件组(event group)信号量(semaphoe)互斥量(mutex)

1. 信号量(Semaphore)

  • 获取/释放:A获取信号量,用完后释放信号量。
  • 阻塞/唤醒:A获取不到信号量则阻塞,B释放信号量并唤醒A。
  • 超时:A获取不到信号量则阻塞,并设置超时时间;A要么超时返回,要么在这段时间内因为B释放信号量而被唤醒。
  • 传递状态:只能传递数量(状态)。

2. 互斥量(Mutex)

  • 获取/释放:A获取互斥量,用完后释放互斥量。
  • 阻塞/唤醒:A获取不到互斥量则阻塞,B释放互斥量并唤醒A。
  • 超时:A获取不到互斥量则阻塞,并设置超时时间;A要么超时返回,要么在这段时间内因为B释放互斥量而被唤醒。
  • 传递状态:只能传递锁的状态。

3. 事件(Event)

  • 获取/释放:A等待事件触发,事件触发后继续执行。
  • 阻塞/唤醒:A等待事件则阻塞,B触发事件并唤醒A。
  • 超时:A等待事件则阻塞,并设置超时时间;A要么超时返回,要么在这段时间内因为B触发事件而被唤醒。
  • 传递状态:可以传递状态。

4. 条件变量(Condition Variable)

  • 获取/释放:A等待条件满足,条件满足后继续执行。
  • 阻塞/唤醒:A等待条件则阻塞,B满足条件并唤醒A。
  • 超时:A等待条件则阻塞,并设置超时时间;A要么超时返回,要么在这段时间内因为B满足条件而被唤醒。
  • 传递状态:可以传递状态。

5. 记忆技巧

  • 信号量:像一个可以计数的量,多个线程可以同时获取,传递的是数量。
  • 互斥量:像一个锁,只有一个线程可以持有,传递的是锁的状态。
  • 事件:像一个信号灯,通知其他线程某个事件发生了,可以传递状态。
  • 条件变量:像一个条件的等待与通知机制,用于等待某个条件的满足,可以传递状态。
内核对 象生产者消费 者数据/状态说明
队列ALLALL数据:若干个数据
谁都可以往队列里扔数据,
谁都可以从队列里读数据
用来传递数据,
发送者、接收者无限制,
一个数据只能唤醒一个接 收者
事件组ALLALL多个位:或、与
谁都可以设置(生产)多个位,
谁都可以等待某个位、若干 个位
用来传递事件,
可以是N个事件,
发送者、接受者无限制,
可以唤醒多个接收者:像 广播
信号量ALLALL数量:0~n
谁都可以增加一个数量,
谁都可消耗一个数量
用来维持资源的个数,
生产者、消费者无限制,
1个资源只能唤醒1个接收 者
任务通 知ALL只有 我数据、状态都可以传输,
使用任务通知时,
必须指定接受者
N对1的关系:
发送者无限制,
接收者只能是这个任务
互斥量只能A开 锁只能A开 锁位:0、1
我上锁:1变为0,
只能由我开锁:0变为1
就像一个空厕所,
谁使用谁上锁,
也只能由他开锁

使用图形对比如下:

  • 队列
    • 存储和传输任意数据,支持多个数据项。
    • 任务和中断服务程序(ISR)都可以使用。
  • 事件组
    • 每个事件用一bit表示,1表示事件发生,0表示未发生。
    • 适合表示单个或组合事件的状态。
    • 广播效果,可唤醒多个等待任务。
  • 信号量
    • 基于计数值,任务或ISR释放信号量时计数值加1,获得时减1。
  • 任务通知
    • 基于任务控制块(TCB)中的数值。
    • 发送时覆盖旧值,需指定接收任务,仅接收任务可获取通知。
  • 互斥量
    • 数值为0或1,用于独占资源。
    • 获得互斥量的任务必须释放互斥量。

显示全文