0.前言
在一个面试环节,考察到RTOS中IPC机制,我当时说出了rt_thread 系统中IPC有互斥量,信号量,邮箱,少说了事件集, 消息队列,信号等 并且为了彰显自己的理解,多说了互斥锁和二值信号量等同,现在来看不是特别确定的还是不能乱说。而且回答上没有条理性回答。
今天就从基本概念上,做一下纠偏,梳理一下RTOS中的IPC,有更清晰的认识 包括但是不限于互斥量和信号量的区别。
以rt_thread为例。
例如一项工作中的两个线程:一个线程从传感器中接收数据并且将数据写到共享内存中,同时另一个线程周期性的从共享内存中读取数据并发送去显示,下图描述了两个线程间的数据传递:
1.为什么引入线程间同步/通信概念呢?
在多线程实时系统中,一项工作的完成往往可以通过多个线程协调的方式共同来完成,那么多个线程之间如何 “默契” 协作才能使这项工作无差错执行?下面举个例子说明。
例如一项工作中的两个线程:一个线程从传感器中接收数据并且将数据写到共享内存中,同时另一个线程周期性的从共享内存中读取数据并发送去显示,下图描述了两个线程间的数据传递:
解决线程之间的无序问题:
首先IPC机制按照通信特性分类(之前的文章提及过链接),分为线程间同步和线程间通信。
同步是按预定的先后顺序进行,线程同步是指多个线程通过特定的机制(互斥量、事件对象,临界区)来控制线程之间的执行顺序,如果没有同步,那线程之间将是无序的(在多线程环境下,如果没有显式同步,线程的执行顺序确实是无序的(由操作系统调度器决定)。抢占式调度会根据优先级、时间片轮转等因素动态切换线程,这种无序性是并发编程的常态,前提是线程之间完全无共享资源或数据依赖,无任何交叉,不然就需要通过同步建立有序态)
什么是临界区呢?
多个线程操作/访问同一块区域(代码),这块代码就称为临界区。e.g.一般共享内存块就是临界区
线程同步方式很多:但是核心思想:在访问临界区的时候只允许一个(或一类)线程运行
进入 / 退出临界区的方式有很多种:
1)调用 rt_hw_interrupt_disable() 进入临界区,调用 rt_hw_interrupt_enable() 退出临界区;详见《中断管理》的全局中断开关内容。
2)调用 rt_enter_critical() 进入临界区,调用 rt_exit_critical() 退出临界区。
多线程实时系统中,为了完成一项工作,往往通过多个线程协调的方式共同完成,那线程之间需要默契协作才能使这项工作无差错执行。
信号量控制块
struct rt_semaphore
{
struct rt_ipc_object parent