实时操作系统Nucleus Plus提供了6种进程间通信方式,分别为:邮箱(mailboxes)、消息队列(queues)和管道(pipes)、信号量(semaphores)、事件集(event groups)和消息(signals)。前三者用于进程间通信,后三者用于进程同步,本文总结了Nucleus Plus进程间通信方式。
i,首先说明Nucleus进程间通信的两个基本概念。
消息(message):由一个或多个字节(byte)或者字(32-bit word,4bytes)组成的信息单元,可在不同进程间传递少量的信息。邮箱(mailboxes)、消息队列(queues)和管道(pipes)通信的构成单元是message。
事件(event)或者信号(signal):一个32-bit word中的每一位bit代表一个信号或者事件,只能用于不同进程间通知某情况出现,不能携带额外的信息。其中一个32-bit word称为一个事件组。这是事件集(event groups)和消息(signals)的构成单元。
ii,邮箱(mailboxes)、消息队列(queues)和管道(pipes)
|
邮箱(mailboxes) |
消息队列(queues) |
管道(pipes) |
消息构成 |
4个32位字 单一消息 |
一个或多个32位字 多个消息 |
一个或多个字节 多个消息 |
任务挂起/唤醒 |
FIFO/进程优先级 |
FIFO/进程优先级 |
FIFO/进程优先级 |
广播/多任务支持 |
支持 |
支持 |
支持 |
动态创建 |
是 |
是 |
是 |
数量限制 |
无 |
无 |
无 |
1,数量限制指的是一个任务所使用的邮箱、消息队列或者管道的数量是否受限。
2,FIFO挂起/唤醒:当能够满足任务要求时,任务唤醒的顺序按照先进先出进行。
3,任务优先级挂起/唤醒:按照被挂起任务的优先级顺序进行唤醒,高优先级优先唤醒。
4,任务挂起/唤醒模式在邮箱、消息队列或者管道被创建时确定。
iii,事件集(event groups)和消息(signals)
信号和事件以及后面介绍的信号量用来解决任务间的同步问题。
信号signal:
异步方式运行,任务提前指定信号处理子程序,每个任务可以处理32个信号,每个信号对应32-bit字的一个位。任务创建时默认信号是disable的,可通过设置信号屏障字的相应位来决定某信号是否使能,屏障字某位设为1表示使能该信号。信号只能是一个进程去通知另一个进程,即不支持广播。
当信号出现,任务中断并且调用信号处理程序,信号被处理后自动清除。信号处理子程序不能被新信号中断。任何新信号的处理在当前信号处理完成后进行。在第一个信号被验证之前再次发送的同样的信号将被丢弃弃。
工程开发中常结合信号和内存队列来实现进程间的数据通信。一个简单的例子,进程A将数据写入一段内存、产生一个相应的全局变量控制结构体,而后通过signal通知进程B去读取;进程B收到signal后根据全局变量控制结构体到相应的内存中将该数据读取处理。
事件event:
同步方式运行,是用于警告某一特定的系统事件已经发生的机制。每个32-bit字成为一个事件集,其中的每一位称作事件标志event flag。event flags的设置set和清除clear以及读取receive可以通过逻辑与/或进行。另外,event flag被读取received后可自动重置。应用程序可能拥有的事件集没有预先的设定。除非主动通过特定的服务申请,任务并不能知道某事件是否已经发生了。(The task does not recognize event flags are present until the specific service request is made.)
例如,一个事件组的32位event flag分配为:5位用于消息队列事件、24位用于标示信号事件,其余3位用于识别事件类型(是消息队列、信号还是超时)。示例代码如下(NU_EventWait函数封装了Nucleus PLUS 事件组函数):
iv,最后是一种特殊的任务间同步手段--信号量(semaphores)
信号量(semaphore):是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件,外部设备)来实现进程间通信,它本身只是一种外部资源的标识。当进程不再使用一个信号量控制的共享资源时,信号量的值+1,对信号量的值进行的增减操作均为原子操作,这是由于信号量主要的作用是维护资源的互斥或多进程的同步访问。