一、线程同步

  • 线程同步的使用场景

    例如一项工作中的两个线程:一个线程从传感器中接收数据并且将数据写到共享内存中,同时另一个线程周期性的从共享内存中读取数据并发送去显示,下图描述了两个线程间的数据传递:

  • 临界区

    多个线程操作 / 访问同一块区域(代码),这块代码就称为临界区,上述例子中的共享内存块就是临界区。

    线程互斥是指对于临界区资源访问的排它性。当多个线程都要使用临界区资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。线程互斥可以看成是一种特殊的线程同步。

  • 线程同步的作用

    简单来说RT-Thread的信号量(semaphore)、互斥量(mutex)、和事件集(event)的作用都是保证共享内存的互斥性。

  • 线程之外的临界区使用

    调用 rt_enter_critical() 进入临界区,调用 rt_exit_critical() 退出临界区;

    调用 rt_hw_interrupt_disable() 进入临界区,调用 rt_hw_interrupt_enable() 退出临界区。(关闭全局中断)

  • rt_enter_critical()的使用场景

    在重定义rt_hw_console_output函数的时候会使用临界区,主要是防止在线程中打印信息时,被高优先级的线程抢占,导致打印信息的异常发生,如下图所示:

信号量

  • 信号量的使用:

    简单来说:信号量时是一个非负数的标识,当信号量大于零时,可以rt_sem_take函数获得信号量,获取信号量后会将标识减 1 而释放信号的过程,便是将标识加1

    注意: rt_sem_take函数无法获取信号时,此线程将挂起等待一段时间,或者永久等待。

  • 信号量的互斥使用

    其实互斥量也是信号量的一种,当信号量值始终在 1 和 0 之间变动时,便可实现锁的功能。

互斥量

互斥量又叫相互排斥的信号量,是一种特殊的二值信号量。

  • 互斥量的使用场景

    互斥量的使用比较单一,因为它是信号量的一种,并且它是以锁的形式存在。在初始化的时候,互斥量永远都处于开锁的状态,而被线程持有的时候则立刻转为闭锁的状态。互斥量更适合于:

    • 线程多次持有互斥量的情况下。这样可以避免同一线程多次递归持有而造成死锁的问题。

    • 可能会由于多线程同步而造成优先级翻转的情况。

事件集

事件集与信号量不同,它的特点是可以实现一对多,多对多的同步。集合可以用一个 32 位无符号整型变量来表示,变量的每一位代表一个事件,线程通过 “逻辑与” 或“逻辑或”将一个或多个事件关联起来,形成事件组合。

注意:如果信息标记同时设置了清除标记位,则当线程 #1 唤醒后将主动把事件 1 和事件 30 清为零,否则事件标志将依然存在(即置 1)。

线程优先级翻转

上面说到,互斥量是信号量的一种,那么为啥还要设计互斥量了,当使用信号量实现锁功能的时候,线程执行的图片如下所示:

注意:从图上可以看出,假设执行到A线成时,无法获取到锁,那么A线程将进入等待状态,并不会被挂起,所以通过信号量实现锁是比较浪费资源的。

那么在使用互斥量会发生什么样的现象,当线程 C 先持有互斥量,而后线程 B 试图持有互斥量,此时线程 3 的优先级被零时提升为和线程 2 的优先级相同。所释放后,线程C将回到原有的优先级

二、线程通信

上面的线程同步中通过信号量、互斥量、事件集的实现保护临界区实现线程中的通信,但是这样的操作会使逻辑变得很复杂,所以RT-Thread提供了线程通信,将线程同步与线程通信的使用场景分开。

邮箱

  • 邮箱的使用场合

    邮箱是一种简单的线程间消息传递方式,特点是开销比较低,效率较高。在 RT-Thread 操作系统的实现中能够一次传递一个 4 字节大小的邮件,并且邮箱具备一定的存储功能,能够缓存一定数量的邮件数 (邮件数由创建、初始化邮箱时指定的容量决定)。邮箱中一封邮件的最大长度是 4 字节,所以邮箱能够用于不超过 4 字节的消息传递。

    注意:因为邮箱一次传递的信息最大长度是 4 字节,所以邮箱很少用于传递实际的信息,都是通过传递信息存放的地址。

消息队列

消息队列是另一种常用的线程间通讯方式,是邮箱的扩展。可以应用在多种场合:线程间的消息交换、使用串口接收不定长数据等。

  • 消息队列的使用场合

    消息队列可以应用于发送不定长消息的场合,包括线程与线程间的消息交换,以及中断服务例程中给线程发送消息(中断服务例程不能接收消息)。下面分发送消息和同步消息两部分来介绍消息队列的使用。

    注意:当创建的是一个所有消息的最大长度是 4 字节的消息队列时,消息队列对象将蜕化成邮箱。

信号

信号(又称为软中断信号),在软件层次上是对中断机制的一种模拟,在原理上,一个线程收到一个信号与处理器收到一个中断请求可以说是类似的。

RT-Thread线程同步与线程通信的更多相关文章

  1. 关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇高质量的博文)

    Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享 ...

  2. 【Java并发002】使用级别:线程同步与线程通信

    一.前言 本文介绍Java多线程技术,分为五个部分:多线程的两种实现方式--继承Thread类和实现Runnable接口:线程同步应用:三人吃苹果:线程同步+线程通信应用之一:生产者-消费者问题:线程 ...

  3. C# 多线程编程第二步——线程同步与线程安全

    上一篇博客学习了如何简单的使用多线程.其实普通的多线程确实很简单,但是一个安全的高效的多线程却不那么简单.所以很多时候不正确的使用多线程反倒会影响程序的性能. 下面先看一个例子 : class Pro ...

  4. iOS开发——高级篇——线程同步、线程依赖、线程组

    前言 对于iOS开发中的网络请求模块,AFNet的使用应该是最熟悉不过了,但你是否把握了网络请求正确的完成时机?本篇文章涉及线程同步.线程依赖.线程组等专用名词的含义,若对上述名词认识模糊,可先进行查 ...

  5. Java线程同步和线程通信

    一.线程同步 当多个线程访问同一个数据时,非常容易出现线程安全问题.这时候就需要用线程同步. 不可变类总是线程安全的,因为它的对象状态是不可改变的,但可变类对象需要额外的方法来保证线程安全. 1.同步 ...

  6. Java并发——线程安全、线程同步、线程通信

    线程安全 进程间"共享"对象 多个“写”线程同时访问对象. 例:Timer实例的num成员,即add()方法是用的次数.即Timer实例是资源对象. class TestSync ...

  7. Java多线程(二) —— 线程安全、线程同步、线程间通信(含面试题集)

    一.线程安全 多个线程在执行同一段代码的时候,每次的执行结果和单线程执行的结果都是一样的,不存在执行结果的二义性,就可以称作是线程安全的. 讲到线程安全问题,其实是指多线程环境下对共享资源的访问可能会 ...

  8. Java-多线程第三篇3种创建的线程方式、线程的生命周期、线程控制、线程同步、线程通信

    1.Java使用Thread类代表线程.     所有的线程对象必须是Thread类或其子类的实例. 当线程继承Thread类时,直接使用this即可获取当前线程,Thread对象的getName() ...

  9. 多线程,线程类三种方式,线程调度,线程同步,死锁,线程间的通信,阻塞队列,wait和sleep区别?

    重难点梳理 知识点梳理 学习目标 1.能够知道什么是进程什么是线程(进程和线程的概述,多进程和多线程的意义) 2.能够掌握线程常见API的使用 3.能够理解什么是线程安全问题 4.能够知道什么是锁 5 ...

  10. Python并发编程-进程 线程 同步锁 线程死锁和递归锁

    进程是最小的资源单位,线程是最小的执行单位 一.进程 进程:就是一个程序在一个数据集上的一次动态执行过程. 进程由三部分组成: 1.程序:我们编写的程序用来描述进程要完成哪些功能以及如何完成 2.数据 ...

随机推荐

  1. 使用Go语言开发一个短链接服务:四、生成code算法

    章节  使用Go语言开发一个短链接服务:一.基本原理  使用Go语言开发一个短链接服务:二.架构设计  使用Go语言开发一个短链接服务:三.项目目录结构设计  使用Go语言开发一个短链接服务:四.生成 ...

  2. 第十三届蓝桥杯大赛软件赛省赛【Java 大学B 组】试题C: 字符统计

    1 import java.util.Scanner; 2 3 public class Main { 4 public static void main(String args[]) { 5 Sca ...

  3. 【已解决】org.apache.thrift.transport.TTransportException: Could not create ServerSocket on address 0.0.0.0/0.0.0.0:9083.

    杀死这些进程 kill -9 进程号

  4. 【放假第1天】采购季倒计时 2G 50/年,4G 618/3年 云服务器选购攻略 阿里云 腾讯云 京东云对比 搭建网站、数据分析

    ​ 更新日期:4月4日(阿里云价格回调,京东云采购季持续进行) <最新对比表>已更新在文章头部-腾讯云文档,文章具有时效性,请以腾讯文档为准! https://docs.qq.com/do ...

  5. 探索基于WebRTC的有感录屏技术开发流程

    第一章:技术原理 WebRTC(Web Real-Time Communication)是一种开放源代码项目,旨在通过浏览器之间的点对点通信实现实时音视频通信.WebRTC利用JavaScript A ...

  6. HMS Core 3D精准室内定位技术,打造“店铺级”出行体验

    2022年4月28日,在华为折叠旗舰及全场景新品发布上,华为Mate Xs 2折叠屏手机搭载由HMS Core定位服务(Location Kit)提供的3D精准室内定位技术,为用户提供了"店 ...

  7. 动态库 DLL 封装二:dll封装方法

    例:我新建的工程是,带lib的MFC规则的DLL 主要有三个文件需要写东西 ( .h /  .cpp  /  .def ) 示例: // a.h ...... #ifdef __cplusplus e ...

  8. Python scipy.ndimage.find_objects用法及代码示例

    用法 scipy.ndimage.find_objects(input, max_label=0) 在标记数组中查找对象. 参数: input: 整数数组 包含由不同标签定义的对象的数组.值为 0 的 ...

  9. go语言结构体使用小结

    转载请注明出处: 在Go语言中,结构体(struct)是一种复合数据类型,它允许你将多个不同类型的字段组合成一个单一的类型.结构体为数据的封装和抽象提供了便利,使得数据组织更加清晰和易于管理. 结构体 ...

  10. nginx重新整理——————nginx 的网络模型[九]

    前言 简单介绍一下nginx的网络模型. 正文 网络拓扑图: 数据流: 网络传输大概是这样传输的. nginx 事件循环: 事件处理过程: 上面两张图什么意思呢? 其实就是说,nginx 是通过事件驱 ...