Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
RT-Thread一般讨论
【2024-RSOC】RT-thread IPC机制
发布于 2024-07-25 21:05:29 浏览:277
订阅该版
[tocm] # RT-Thread IPC **本文章为RT-Thread5.0.x版本** # 一、IPC机制 ![image-20240724202544361](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101032.png) RT-Thread中的IPC可以分成了两大块: * 线程同步 * 线程间通信 # 二、线程同步 线程同步主要是为了保证多个线程在访问共享资源时的正确性和一致性,避免由于竞争条件导致的数据不一致和程序错误。 线程同步是通过多种机制来实现的,主要包括信号量、互斥量、事件集。 ## 1.信号量 信号量是一种轻型的用于解决线程间同步问题的内核对象,一个或多个运行线程可以获取或释放它,从而达到同步或互斥的目的。用于实现任务与任务之间、任务与中断处理程序之间的同步与互斥。 **信号量可以是二值信号量或计数信号量。** * **二值信号量**:顾名思义,只有两个状态,类似于互斥锁,用于确保只有一个线程可以访问共享资源。 * **计数信号量**:用于限制对资源的访问数量。 具体信号量使用的API可以[参考文档中心](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1?id=%e4%bf%a1%e5%8f%b7%e9%87%8f)。下面重点讲述信号量的管理机制。 ![信号量相关接口](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/ipc1/figures/06sem_ops.png) ### a.信号量控制块 ![image-20240724210750568](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101033.png) ### b.获取信号量 ![image-20240724211044023](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101034.png) 路径:`.\rt-thread\src\ipc.c` 这个是获取信号量的API,我们来看一下内部是怎么实现的。 ![image-20240724211912880](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101035.png) 获取信号量可以大致分为这几种情况: * 信号量不为0 ![image-20240724212205065](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101036.png) * 信号量为0 * 不等待 ![image-20240724212546146](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101037.png) * 等待 ![image-20240724213937574](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101039.png) ![image-20240724214312692](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101040.png) 笔者手误了,这边应该是把线程从就绪链表中移除,并添加到信号量的挂起链表,当有信号量释放的时候,就会判断挂起链表中是否有线程,并把其他变为就绪链表。(为什么不重新打就是因为懒,qq截图不能直接重新编辑,不知道有什么比较好的工具) 线程的超时回调函数 ![image-20240724214054167](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101041.png) ### c.释放信号量 路径:`.\rt-thread\src\ipc.c` ![image-20240724221007184](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101042.png) 路径:`.\rt-thread\src\ipc.c` ![image-20240724221513151](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101043.png) 路径:`.\rt-thread\src\scheduler_comm.c` ![image-20240724221811800](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101044.png) 如果在等待时间内的想获取信号量的线程就会被重新调度。 ## 2.互斥量 互斥量又叫相互排斥的信号量,是一种特殊的二值信号量。互斥量类似于只有一个车位的停车场:当有一辆车进入的时候,将停车场大门锁住,其他车辆在外面等候。当里面的车出来时,将停车场大门打开,下一辆车才可以进入。 **互斥量与信号量不同的点:** * 只能由持有线程释放 * 解决线程优先级翻转问题(会将持有线程优先级提高跟等待线程一样) 重点看一下互斥量是怎么解决优先级翻转问题的。 ![互斥量相关接口](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/ipc1/figures/06mutex_ops.png) ### a.互斥量控制块 路径:`.\rt-thread\src\ipc.c` ![image-20240724222511208](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101045.png) 路径:`.\rt-thread\include\rtdef.h` ![image-20240724224623138](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101046.png) ### b.获取互斥量 ![image-20240724233418934](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101047.png) 路径:`.\rt-thread\src\ipc.c` ![image-20240724230443967](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101048.png) **获取互斥量可以分成这几种情况:** * 拥有者 * hold++ ![image-20240724231014144](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101049.png) * 不是拥有者 * 互斥量还未被拥有 ![image-20240724232013121](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101050.png) * 互斥量已经被拥有 * 不等待 ![image-20240724233914775](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101051.png) * 等待 将线程移至互斥量的挂起链表,并设置亮着为互斥对象,以及判断是否比当前挂起的线程中优先级高 ![image-20240724234442936](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101052.png) 设置定时器,发起调度。 ![image-20240724234934057](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101053.png) ![image-20240724235653165](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101054.png) ### c.释放互斥量 路径:`.\rt-thread\src\ipc.c` ~~~c rt_err_t rt_mutex_release(rt_mutex_t mutex) ~~~ **释放信号量大致可以分为这几种情况:** * 不是拥有着 ![image-20240725132933467](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101055.png) * 是拥有着且拥有的互斥锁为0 * 没有其他线程想获取互斥量 ![image-20240725134714657](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101056.png) * 有其他线程想获取互斥量 ![image-20240725134537569](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101057.png) ![image-20240725135256987](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101058.png) ## 3.事件集 事件集用于线程之间的事件通知和同步。一个事件集包含多个事件标志,线程可以等待一个或多个事件标志。 至于API参考[官方文档](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1?id=%e4%ba%8b%e4%bb%b6%e9%9b%86) ![事件相关接口](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/ipc1/figures/06event_ops.png) ### a.事件集控制块 路劲:`rt-thread\include\rtdef.h` ![image-20240725131539502](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101059.png) ### b.接收事件 路径:`.\rt-thread\src\ipc.c` ![image-20240725172802964](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101060.png) ![image-20240725173127850](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101061.png) * 接收成功 ![image-20240725173441425](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101062.png) * 接收不成功 * 不等待 ![image-20240725173605897](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101063.png) * 等待 ![image-20240725173821148](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101064.png) ![image-20240725174002779](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101065.png) ### c.发送事件 路径:`rt-thread\src\ipc.c` ![image-20240725174450872](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101066.png) * 是否有线程挂起 ![image-20240725175250211](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101067.png) # 三、线程间的通信 在裸机编程中,经常会使用全局变量进行功能间的通信,如某些功能可能由于一些操作而改变全局变量的值,另一个功能对此全局变量进行读取,根据读取到的全局变量值执行相应的动作,达到通信协作的目的。RT-Thread 中则提供了更多的工具帮助在不同的线程中间传递信息。 ## 1.邮箱 邮箱用于在线程之间传递固定大小的消息。每次发送和接收的消息大小都是固定的。邮箱适用于需要简单、高效传递固定大小数据的场景。 ### a.邮箱控制块 路径:`.\rt-thread\include\rtdef.h` ![image-20240725181054128](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101068.png) ![image-20240725202726514](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101069.png) ### b.接收邮箱 路径:`.\rt-thread\src\ipc.c` ![image-20240725181326801](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101070.png) **接收邮箱可以大致分为这几种情况:** * 没有邮箱且不等待 ![image-20240725181929529](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101071.png) ![image-20240725182808872](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101072.png) * 没有邮箱且等待 ![image-20240725201137351](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101073.png) ![image-20240725201232969](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101074.png) ![image-20240725201405991](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101075.png) ### c.发送邮箱 路径:`.\rt-thread\src\ipc.c` ![image-20240725201512602](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101076.png) * 满了不等待 ![image-20240725201831043](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101077.png) * 满了等待 ![image-20240725202018130](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101078.png) * 成功发送邮箱 ![image-20240725202256438](https://cdn.jsdelivr.net/gh/CYFS3/Typroa/202407252101079.png) ## 2.消息队列 消息队列用于在线程之间传递可变大小的消息,可以设置消息的优先级。消息队列适用于需要传递不同大小数据和具有优先级调度需求的场景。 邮箱队列的机制跟邮箱大致一样,不同的是两者可以传递的消息大小不一样。
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
CYFS
这家伙很懒,什么也没写!
文章
6
回答
2
被采纳
0
关注TA
发私信
相关文章
1
有关动态模块加载的一篇论文
2
最近的调程序总结
3
晕掉了,这么久都不见layer2的踪影啊
4
继续K9ii的历程
5
[GUI相关] FreeType 2
6
[GUI相关]嵌入式系统中文输入法的设计
7
20081101 RT-Thread开发者聚会总结
8
嵌入式系统基础
9
linux2.4.19在at91rm9200 上的寄存器设置
10
[转]基于嵌入式Linux的通用触摸屏校准程序
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部