把多任务系统当做一个团队,每一个任务相当团队里的一个人。团队成员之间要协调工作进度(同步)、争用会议室(互斥)、沟通(通信)。多任务系统中所涉及的概念,都可以在现实生活中找到例子。
各类RTOS都会涉及这些概念:任务通知(task notification)、队列(queue)、事件组(event group)、信号量(semaphoe)、互斥量(mutex)等。
4.1 同步与互斥的概念
这两个概念比较容易混淆,这里用通俗的举例解释。
同步:任务之间的依赖,比如A任务的运行依赖于B任务产生的数据。例如:在团队活动里,同事A写完报表,经理B才能拿去向领导汇报。经理B必须等同事A完成报表,AB之间有依赖。
互斥:对资源同时访问时,只能有一个获得资源,一个使用完后才能轮到下一个,往往需要进行互斥访问。例如:打印机同一时间内只能打印一个任务;A、B两人抢厕所,A先一步占用了,B只能等A用完再用。
4.2 实现同步、互斥的内核方法 对比
能实现同步、互斥的内核方法有:任务通知(task notification)、队列(queue)、事件组(event group)、信号量(semaphoe)、互斥量(mutex)。
它们都有类似的操作方法:获取/释放、阻塞/唤醒、超时。
内核对象 | 生产者 | 消费者 | 数据/状态 | 说明 |
---|---|---|---|---|
队列 | ALL | ALL | 里面 可以放任意多个数据; 任务、ISR都可以放入(生产)数据; 任务、ISR都可以读出(消费)数据; | 用来传递数据, 发送者、接收者无限制, 一个数据只能唤醒一个接收者 |
事件组 | ALL | ALL | 一个事件用一bit表示: 1表示事件发生了, 0表示事件没发生; | 用来传递事件, 可以是N个事件, 发送者、接受者无限制, 可以唤醒多个接收者:像广播 |
信号量 | ALL | ALL | 核心是"计数" 任务、ISR释放信号量时,让计数加1; 任务、ISR获得信号量时,让计数减1; | 用来维持资源的个数, 像停车场,出来一个,才能进去一个 |
任务通知 | ALL | 只有我 | 数据、状态都可以传输,核心是任务的TCB里的数值,会被覆盖; 发通知给谁?必须指定接收任务; 只能由接收任务本身获取该通知; | N对1的关系: 发送者无限制, 接收者只能是这个任务 |
互斥量 | A上锁 | A开锁 | 数值只有0或1 我上锁:1变为0, 只能由我开锁:0变为1 | 就像一个空厕所, 谁使用谁上锁, 也只能由他开锁 |