前言
本节简要的介绍什么是任务的同步以及实现任务通信的几种方式:信号量、消息邮箱、消息队列等等。
程序中的各个任务通常要相互配合才能完成一个功能。比如任务运行时经常需要无冲突的访问某一种资源,或者某个任务必须在前一个任务完成之后才能开始等等。这些情况就必须要任务间能进行通信。
任务的同步
为了实现各个任务之间的合作和无冲突的运行,必须要在任务间建立一些制约关系,常见的有直接制约关系和间接制约关系
直接制约关系
直接制约关系源于任务间的合作。比如任务运行顺序的先后,假设我要打印一份文档,这件事包含两个任务,任务A是:先做一份电子档;任务B是:开始打印。显然,任务B必须在任务A完成之后才能开始,如果这两个任务不能如此协调工作,势必将造成严重的后果(浪费纸)。这种任务间的合作就是直接制约关系。
间接制约关系
间接制约关系源于对资源的共享。一般是某个资源在同一时间只能有一个(或者几个)任务使用,假设某个资源一次只能一个任务使用,那么当这个资源被某个任务使用时,其他准备使用这个资源的任务都只能等待。
因此操作系统应该至少能解决这两种问题,第一:各任务间应该有一种互斥关系,某个任务在使用时,其它任务不能使用;第二:某些任务之间要有先后执行顺序。这种制约性的合作就叫做同步。
事件
uC/OS-II使用信号量、消息邮箱、消息队列来作为中间环节实现任务间的通信。这些中间环节也叫事件。
发送事件与请求事件
发送信息的任务称为发送方,发送方将信息发到事件上称为发送事件。
同理,接收信息的任务称为接收方,接收方从事件上接收信息的过程叫做请求事件。
这些操作在uC/OS-II中都有对应的全局函数可以调用。
信号量
在讨论信号量之前先来看看信号。什么是信号。信号就是一个标志,共享资源的一个标志,表示该资源的占用情况。这样当任务访问这个资源时,先对标志进行查看,如果该资源还有,那么就可以使用;反之则等待。
这个和电话亭的使用规则很像,如果在电话亭门口设立一盏灯,灯亮表示里面有人,灯不亮表示里面没人,那么当用户去打电话时就可以通过查看电话亭外面的灯来判断里面是不是有人了。这就是信号,也是一个二值信号量或者说互斥信号量。
前面提到过一个词:二值信号量。二值信号量说明这个信号只有两个值可以取。如果某天电话亭扩张了,可以容纳多个人了,那么再设置这样的灯就不合理了;而应该设置一个计数器,进去一个人就自动减1,出来一个人就自动加1;初值应该就是电话亭的容量。这种信号就是信号量。
消息邮箱
任务与任务之间往往需要传递数据,为了达到这个目的,可以在内存中开辟一块缓冲区,将数据放在这个缓冲区里面;发送方往这个缓冲区里面写,接收方往这个缓冲区里面读就好了。也就是说只要传递这个缓冲区的指针就好了。写的过程叫发送消息,读的过程的读取/请求消息。
消息队列
消息队列就是在消息邮箱之间加一个指针数组,数组的每个元素都指向一个缓冲区,这样任务之间传递的时候就只需要传递这个指针数组的地址就好了。根据指针数组这个地址找到指针数组,然后再找到具体的消息缓冲区。
参考资料
嵌入式实时操作系统uC/OS-II原理及应用