RT-Thread进程间通信(IPC)各工作方式分析

IPC功能划分

在实际应用中,有些情况需要在线程间或中断与线程间传输一定的数据(通信),有些情况下,只需要标记一种状态,并不需要传输具体的数据(同步);基于此,rt-thread中的ipc可以大致分为以下两种:
线程间通信:
1.邮箱mb;
2.消息队列msq;

线程间同步:
1.信号量sem;
2.互斥量mutex;
3.事件集event;

通讯IPC

邮箱(mailbox)

知识点如下:
1.一封邮件仅可传输4字节数据内容(规定),在32位系统中,4字节相当于一个指针的大小;因此,在需要传输较多数据时,可通过创建结构体,使用指针指向地址的方式传输;
2.发送和接收邮件都支持超时阻塞机制(send函数无阻塞,send_wait函数有阻塞,recv函数有阻塞);
3.线程、中断都可发送邮件,但注意,中断服务函数不允许任何阻塞,所以中断发送邮件必须选择非阻塞方式;
4.中断服务函数中不能接收邮件,因为中断不可阻塞;
5.一个线程可从任何一个邮箱接收和发送邮件;
6.多个线程可以向同一个邮箱发送和接收邮件;
7.FIFO、PRIO两种阻塞唤醒方式(线程等待邮件资源而阻塞);
8.邮箱中有entery表示邮箱可用邮件数,in_offset,out_offset指针指向邮件存放地址偏移量(自加1偏移4个字节),初始化为0,线程发送一个邮件到邮箱,entery +1,in_offset+1,若邮箱满了则in_offset清0;线程从邮箱接收一个邮件,entery-1,out_offset+1,若邮箱空了则out_offset清0;
9.若邮箱中有邮件,接收线程接收时,其实是复制邮箱中4字节的内容到接收地址中;

消息队列(messagequeue)

知识点如下:
1.消息队列是邮箱的扩展,其可接收线程和中断发送的不固定长度的消息;
2.读消息队列(接收)支持超时阻塞机制(send函数无阻塞,recv函数有阻塞);
3.线程、中断都可以发送消息给消息队列;
4.中断服务函数中不能接收消息,因为中断不可阻塞;
5.一个线程可从任何一个消息队列接收和发送邮件;
6.多个线程可以向同一个消息队列发送和接收邮件;
7.FIFO、PRIO两种阻塞唤醒方式(线程等待邮件资源而阻塞);
8.支持发送紧急消息,将消息放在队列的头部(正常是放尾部)。
9.当空闲消息链表上有空闲消息块时,线程或中断将消息复制到该消息块上,然后将该消息块挂在消息队列的尾部。若无空闲消息块,要发送消息的线程和中断会受到错误码;
10.消息队列中有entry表示队列中可用消息个数,msg_queue_head链表头指针指向即将读取数据的节点,线程读取走一个消息,entry-1,msg_queue_head指向下一个消息,如果继续读取消息直到尾部,则msg_queue_tail指向NULL;msg_queue_tail链表尾指针指向写入的数据节点,线程发送一个消息,entry+1,msg_queue_tail指向当前新写入的消息;

同步IPC

信号量(semaphore)

知识点如下:
1.信号量值非负,value数值表示当前可用资源数,不传输数据内容,常用来同步。
2.二值信号量取值范围(0-1),多值信号量取值范围(0-65535);
3.获取信号量有超时阻塞机制(take函数有阻塞,try_take函数无阻塞,release函数无阻塞);
4.线程和中断都可以释放信号量,信号量无所有权,任何线程或中断都可以释放。
5.获取信号量则value-1,释放信号量value+1;
6.FIFO、PRIO两种阻塞唤醒方式(线程等待信号量资源而阻塞);
7.一般不用信号量做互斥,易出现优先级翻转问题(低优先级获取资源运行,高优先级等待资源阻塞)。
8.二值信号量使用示例:
[1 ] 创建信号量,初始化value=0,表示当前无资源可用;
[2 ] 线程1试图访问该资源时,由于value=0,线程2阻塞;
[3] 线程2或中断在满足某条件后,释放信号量,value=1,表示有资源可用;
[4] 阻塞的线程1获取到信号量,恢复就绪态,value=0,表示无资源可用,此时访问该资源的线程会阻塞;
由上述过程:只有线程2或者中断执行之后,线程1才会执行,实现线程2或中断与线程1之间的同步。

互斥量(mutex)

知识点如下:
1.初始化时,value=1,表示互斥量处于开锁状态,可被持有。常用来保护临界资源。
2.互斥量只能在线程中使用,不可在中断中使用;
3.获取互斥量有超时阻塞机制(take函数有阻塞,release函数无阻塞);
4.互斥量有所有权,其只能被持有线程释放,该线程具有此互斥量的所有权,其余线程不能同时持有该互斥量;
5.已持有互斥量的线程,再次获取该互斥量时,不会挂起(递归访问),但持有量计数加1;
6.保证每个时刻只有一个线程正在访问该互斥量保护的临界资源(闭锁);其他任何优先级的线程想访问该资源时都会阻塞;
7.FIFO、PRIO两种阻塞唤醒方式(线程等待互斥量资源而阻塞);
8.优先级继承:暂时提高持有互斥量线程的优先级,执行完毕后,释放互斥量时,恢复原有优先级。该方法不会彻底解决优先级翻转问题,只是缓解影响。

事件集(event)

知识点如下:
1.set值只表示事件状态(0:未发生,1:已发生),不传输具体数据内容;
2.事件集用32位无符号整型变量set,每一位表示一个事件,共32个事件。
3.获取事件有超时阻塞机制(send函数无阻塞,recv函数有阻塞);
4.中断可发送事件;
5.一个线程可等待多个事件(逻辑与:全部发生才有效,逻辑或:有一个发生即有效);
6.多个线程等待多个事件(逻辑与:全部发生才有效,逻辑或:有一个发生即有效);
7.事件无排队性,多次向线程发送同一事件,若线程未来得及读走该事件,其效果等同于只发一次;
8.FIFO、PRIO两种阻塞唤醒方式(线程等待事件资源而阻塞);
9.事件集与信号量的对比:
事件集:发送操作不可计数;
信号量:释放操作可计数;

事件集:接收(recv)线程可等待多种事件;
信号量:获取(take)线程不能同时等待多种类型的释放,只能识别单一的释放动作;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值