需要获取更好阅读体验的同学,请访问我专门设立的站点查看,地址:http://rtos.100ask.net/
本教程连载中,篇章会比较多,为方便同学们阅读,点击这里可以查看文章的 目录列表,目录列表页面地址:https://blog.csdn.net/thisway_diy/article/details/121399484
本章是概述性的内容。可以把多任务系统当做一个团队,里面的每一个任务就相当于团队里的一个人。团队成员之间要协调工作进度(同步)、争用会议室(互斥)、沟通(通信)。多任务系统中所涉及的概念,都可以在现实生活中找到例子。
各类RTOS都会涉及这些概念:任务通知(task notification)、队列(queue)、事件组(event group)、信号量(semaphoe)、互斥量(mutex)等。我们先站在更高角度来讲解这些概念。
一句话理解同步与互斥:我等你用完厕所,我再用厕所。
同步与互斥经常放在一起讲,是因为它们之的关系很大,“互斥”操作可以使用“同步”来实现。我“等”你用完厕所,我再用厕所。这不就是用“同步”来实现“互斥”吗?
再举一个例子。在团队活动里,同事A先写完报表,经理B才能拿去向领导汇报。经理B必须等同事A完成报表,AB之间有依赖,B必须放慢脚步,被称为同步。在团队活动中,同事A已经使用会议室了,经理B也想使用,即使经理B是领导,他也得等着,这就叫互斥。经理B跟同事A说:你用完会议室就提醒我。这就是使用"同步"来实现"互斥"。
有时候看代码更容易理解,伪代码如下:
01 void 抢厕所(void)
02 {
03 if (有人在用) 我眯一会;
04 用厕所;
05 喂,醒醒,有人要用厕所吗;
06 }
假设有A、B两人早起抢厕所,A先行一步占用了;B慢了一步,于是就眯一会;当A用完后叫醒B,B也就愉快地上厕所了。
在这个过程中,A、B是互斥地访问“厕所”,“厕所”被称之为临界资源。我们使用了“休眠-唤醒”的同步机制实现了“临界资源”的“互斥访问”。
同一时间只能有一个人使用的资源,被称为临界资源。比如任务A、B都要使用串口来打印,串口就是临界资源。如果A、B同时使用串口,那么打印出来的信息就是A、B混杂,无法分辨。所以使用串口时,应该是这样:A用完,B再用;B用完,A再用。
能实现同步、互斥的内核方法有:任务通知(task notification)、队列(queue)、事件组(event group)、信号量(semaphoe)、互斥量(mutex)。
它们都有类似的操作方法:获取/释放、阻塞/唤醒、超时。比如:
这些内核对象五花八门,记不住怎么办?我也记不住,通过对比的方法来区分它们。
内核对象 | 生产者 | 消费者 | 数据/状态 | 说明 |
---|---|---|---|---|
队列 | ALL | ALL |
数据:若干个数据 谁都可以往队列里扔数据, 谁都可以从队列里读数据 |
用来传递数据, 发送者、接收者无限制, 一个数据只能唤醒一个接收者 |
事件组 | ALL | ALL |
多个位:或、与 谁都可以设置(生产)多个位, 谁都可以等待某个位、若干个位 |
用来传递事件, 可以是N个事件, 发送者、接受者无限制, 可以唤醒多个接收者:像广播 |
信号量 | ALL | ALL |
数量:0~n 谁都可以增加一个数量, 谁都可消耗一个数量 |
用来维持资源的个数, 生产者、消费者无限制, 1个资源只能唤醒1个接收者 |
任务通知 | ALL | 只有我 |
数据、状态都可以传输, 使用任务通知时, 必须指定接受者 |
N对1的关系: 发送者无限制, 接收者只能是这个任务 |
互斥量 | 只能A开锁 | A上锁 |
位:0、1 我上锁:1变为0, 只能由我开锁:0变为1 |
就像一个空厕所, 谁使用谁上锁, 也只能由他开锁 |
使用图形对比如下:
全部0条评论
快来发表一下你的评论吧 !