RT-Thread互斥量

文章目录

  • 前言
  • 一、RT-Thread互斥量的概念
  • 二、互斥量和信号量的区别
  • 三、互斥量的函数使用
    • 1.创建互斥量
    • 2.删除互斥量
    • 3.获取互斥量
    • 4.释放互斥量
  • 四、互斥量的基本使用
  • 五、FreeRTOS中互斥量和RT-Thread互斥量的区别
  • 总结


前言

本篇文章将为大家讲解RT-Thread中的互斥量概念和使用方法,以及和信号量的对比,及RT-Thread中的互斥量和FreeRTOS中互斥量的比较。

一、RT-Thread互斥量的概念

在 RT-Thread 中,互斥量(Mutex,互斥锁)是一种用于多线程编程的同步原语,用于确保共享资源在任意时刻只被一个线程访问。互斥量的概念和作用如下:

1.确保共享资源的互斥访问:互斥量用于保护对共享资源的访问,确保在任意时刻只有一个线程可以访问该资源。这样可以避免多个线程同时修改共享资源而导致的数据不一致或竞态条件。

2.实现临界区保护:互斥量通常用于实现临界区保护,将对共享资源的访问限制在临界区内。只有获取了互斥量的线程才能进入临界区,其他线程需要等待互斥量释放后才能进入。

3.防止死锁和资源竞争:RT-Thread 的互斥量实现通常会考虑死锁和资源竞争的问题。互斥量的实现会遵循一定的规则和算法,以确保线程获取互斥量的顺序和释放的顺序是一致的,从而避免死锁的发生。

4.提供更细粒度的同步机制:相比信号量,互斥量提供了更细粒度的同步机制。它通常用于保护单个共享资源或临界区,而信号量则更适合用于限制对资源数量的访问。

二、互斥量和信号量的区别

在RT-Thread中,互斥量(Mutex)和信号量(Semaphore)都是用于线程同步的机制,但它们在功能和使用上有一些区别。

互斥量(Mutex)

  1. 功能:互斥量用于保护共享资源,确保在任何时候只有一个任务可以访问该资源。当一个任务持有互斥量时,其他任务需要访问该资源会被阻塞,直到互斥量被释放。

  2. 特点

    • 互斥量可以看作是一种二进制信号量,只有两种状态:被锁定和未锁定。
    • 只有成功获取互斥量的任务才能继续执行临界区代码,其他任务在获取失败时会被阻塞。
    • 互斥量可以解决优先级翻转问题,即当一个低优先级任务持有互斥量时,系统会提升其优先级到需要访问该资源的最高优先级任务的优先级,以防止高优先级任务被阻塞。
  3. 使用场景:适用于需要临界区保护的情况,例如对共享资源的读写操作。

信号量(Semaphore)

  1. 功能:信号量用于控制资源的访问数量,可以允许多个任务同时访问共享资源。信号量的值表示可用资源的数量,任务在访问资源前会尝试获取信号量,成功获取后资源数量减一,释放资源后信号量增加。

  2. 特点

    • 信号量是一种计数信号量,可以有多个状态。
    • 可以用于限制同时访问共享资源的任务数量。
    • 不能解决优先级翻转问题,因为对于信号量而言,获取信号量的任务只是减少信号量计数,并不会影响任务的优先级。
  3. 使用场景:适用于控制资源访问数量的情况,例如控制同时连接的任务数量、限制缓冲区大小等。

互斥量适用于保护临界资源的情况,并且可以解决优先级翻转问题;而信号量适用于控制资源访问数量的情况,但不能解决优先级翻转问题。

优先级翻转:

优先级翻转(Priority Inversion)是指一个较低优先级的任务(Task A)持有了一个较高优先级任务(Task B)所需要的资源而导致的情况,从而使得较高优先级任务被阻塞或延迟执行的现象。

这种情况通常发生在多任务系统中,其中任务的优先级不同,且存在共享资源。当一个低优先级任务获得了一个高优先级任务所需的资源(如互斥量、信号量等)并持有该资源时,如果此时另一个高优先级任务处于就绪态,需要访问该资源,那么该高优先级任务将被阻塞,等待低优先级任务释放资源。这样,本应优先执行的高优先级任务却被低优先级任务所阻塞,导致优先级翻转。

优先级翻转可能会导致系统性能下降,因为高优先级任务被阻塞时,系统无法及时响应高优先级任务的请求,从而影响了系统的实时性和响应性能。为了解决优先级翻转问题,通常采取以下几种方法:

  1. 优先级继承(Priority Inheritance):当一个低优先级任务持有了一个高优先级任务所需的资源时,系统会将低优先级任务的优先级提升到需要访问该资源的最高优先级任务的优先级,直到低优先级任务释放资源。这样可以避免高优先级任务被阻塞的情况。

  2. 优先级屏蔽(Priority Ceiling):给每个共享资源定义一个优先级屏蔽值,当一个任务获取了资源时,系统将其优先级提升到该资源的优先级屏蔽值,直到释放资源。这样可以确保在任何时候只有一个任务可以访问资源,并且高优先级任务不会被阻塞。

  3. 不可抢占(Non-preemptive):在一些实时操作系统中,可以采用不可抢占的策略,即任务只有在主动放弃CPU时才会被调度让出,而不会因为优先级低而被其他任务抢占。这样可以避免因优先级翻转而导致的问题。

三、互斥量的函数使用

1.创建互斥量

这两个函数是用于创建和初始化互斥量的函数,它们在RT-Thread中用来管理任务之间的互斥访问。

rt_mutex_create(const char* name, rt_uint8_t flag):

参数:
name: 互斥量的名称,用于标识互斥量。
flag: 互斥量的标志位,可以选择是否自动获取。当设置为RT_IPC_FLAG_PRIO时,表示互斥量的优先级继承特性,即互斥量持有者的优先级将会被提升到等待此互斥量的最高优先级。

返回值:
如果成功创建互斥量,则返回一个指向互斥量对象的句柄。
如果创建失败,则返回RT_NULL。

rt_err_t rt_mutex_init(rt_mutex_t mutex, const char* name, rt_uint8_t flag):

参数:
mutex: 互斥量句柄,即通过rt_mutex_create创建的互斥量对象。
name: 互斥量的名称,用于标识互斥量。
flag: 互斥量的标志位,可以选择是否自动获取。当设置为RT_IPC_FLAG_PRIO时,表示互斥量的优先级继承特性,即互斥量持有者的优先级将会被提升到等待此互斥量的最高优先级。

返回值:
如果成功初始化互斥量,则返回RT_EOK。
如果初始化失败,则返回相应的错误码,比如RT_ERROR或RT_ENOMEM等。

这两个函数的作用是创建和初始化互斥量,其中rt_mutex_create函数可以用于创建一个新的互斥量对象,并返回一个句柄;而rt_mutex_init函数则是对已经存在的互斥量进行初始化,使之具备可用状态。

2.删除互斥量

这两个函数是用于删除和分离互斥量的函数,它们在RT-Thread中用于释放互斥量资源,以及取消互斥量与任务之间的关联。

1.rt_err_t rt_mutex_delete(rt_mutex_t mutex):

  • 参数:

    • mutex: 互斥量句柄,即通过rt_mutex_create创建的互斥量对象。
  • 返回值:

    • 如果成功删除互斥量,则返回RT_EOK
    • 如果删除失败,则返回相应的错误码,比如RT_ERROR等。
  • 功能:

    • 该函数用于删除一个已经存在的互斥量对象,释放相应的资源,并且取消与此互斥量相关联的任务关系。
  1. rt_err_t rt_mutex_detach(rt_mutex_t mutex):
    • 参数:

      • mutex: 互斥量句柄,即通过rt_mutex_create创建的互斥量对象。
    • 返回值:

      • 如果成功分离互斥量,则返回RT_EOK
      • 如果分离失败,则返回相应的错误码,比如RT_ERROR等。
    • 功能:

      • 该函数用于分离一个已经存在的互斥量对象,取消与此互斥量相关联的任务关系,但不会释放互斥量资源,互斥量本身仍然存在。

这两个函数的作用是用于释放互斥量资源和取消互斥量与任务之间的关联。rt_mutex_delete函数会删除互斥量对象并释放相关资源,而rt_mutex_detach函数则只是取消与互斥量相关联的任务关系,但不释放互斥量资源。

3.获取互斥量

这两个函数都用于获取互斥量的访问权限,但在不同的情况下有不同的行为:

  1. rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time):

    • 参数:
      • mutex: 互斥量句柄,即通过rt_mutex_create创建的互斥量对象。
      • time: 等待互斥量的超时时间,单位为系统时钟节拍。如果设置为RT_WAITING_FOREVER,则表示无限等待;如果设置为RT_WAITING_NO,表示不等待。
    • 返回值:
      • 如果成功获取互斥量的访问权限,则返回RT_EOK
      • 如果等待超时,则返回RT_ETIMEOUT
      • 如果出现错误,则返回相应的错误码,比如RT_ERROR等。
    • 功能:
      • 该函数尝试获取互斥量的访问权限,如果互斥量当前被其他任务占用,则当前任务会被阻塞,直到互斥量被释放或超时。
      • 如果设置了超时时间,任务会在超时时间内等待,超时后函数返回超时错误码。
      • 如果不设置超时时间,则任务会一直等待直到互斥量被释放。
  2. rt_err_t rt_mutex_trytake(rt_mutex_t mutex):

    • 参数:
      • mutex: 互斥量句柄,即通过rt_mutex_create创建的互斥量对象。
    • 返回值:
      • 如果成功获取互斥量的访问权限,则返回RT_EOK
      • 如果互斥量已被其他任务占用,则返回RT_EBUSY
      • 如果出现其他错误,则返回相应的错误码,比如RT_ERROR等。
    • 功能:
      • 该函数尝试获取互斥量的访问权限,与rt_mutex_take不同的是,如果互斥量当前被其他任务占用,当前任务不会被阻塞,而是立即返回获取失败的错误码。

这两个函数允许任务在使用临界资源时进行同步,确保只有一个任务可以访问关键资源。rt_mutex_take函数会在获取互斥量失败时进行等待,而rt_mutex_trytake函数则会立即返回失败,不进行等待。

4.释放互斥量

rt_err_t rt_mutex_release(rt_mutex_t mutex) 函数用于释放由互斥量控制的临界资源,让其他任务可以访问该资源。具体讲解如下:

  • 参数

    • mutex:互斥量句柄,即通过 rt_mutex_create 创建的互斥量对象。
  • 返回值

    • 如果成功释放互斥量的访问权限,则返回 RT_EOK
    • 如果出现错误,则返回相应的错误码,比如 RT_ERROR 等。
  • 功能

    • 该函数用于释放任务持有的互斥量,使其他任务可以获取该互斥量的访问权限。
    • 一般情况下,只有成功获取了互斥量的任务才能调用该函数进行释放。
    • 释放互斥量后,其他等待该互斥量的任务将会根据其优先级重新竞争该资源的访问权限。

四、互斥量的基本使用

#include <rtthread.h>// 定义一个互斥量对象
static struct rt_mutex mutex;// 定义一个线程函数,用于演示互斥量的使用
static void thread_entry(void *parameter)
{rt_err_t result;// 获取互斥量result = rt_mutex_take(&mutex, RT_WAITING_FOREVER);if (result == RT_EOK){rt_kprintf("Thread %s acquired mutex successfully!\n", rt_thread_self()->name);// 在这里可以执行临界区代码,操作共享资源rt_thread_mdelay(1000); // 模拟对共享资源的访问// 释放互斥量rt_mutex_release(&mutex);rt_kprintf("Thread %s released mutex successfully!\n", rt_thread_self()->name);}else{rt_kprintf("Thread %s failed to acquire mutex!\n", rt_thread_self()->name);}
}// 创建一个互斥量的示例
static int mutex_example_init(void)
{rt_err_t result;// 初始化互斥量result = rt_mutex_init(&mutex, "mutex", RT_IPC_FLAG_PRIO);if (result != RT_EOK){rt_kprintf("Failed to initialize mutex! Error code: %d\n", result);return -1;}// 创建线程,用于演示互斥量的使用rt_thread_t tid = rt_thread_create("thread", thread_entry, RT_NULL, 1024, 25, 10);if (tid != RT_NULL){rt_thread_startup(tid);}else{rt_kprintf("Failed to create thread!\n");return -1;}return 0;
}
// 初始化线程
INIT_APP_EXPORT(mutex_example_init);

五、FreeRTOS中互斥量和RT-Thread互斥量的区别

FreeRTOS中的互斥量:

在FreeRTOS中,互斥量是通过函数 xSemaphoreTake() 和 xSemaphoreGive() 来获取和释放的。
与任务关联,任务可以获取和释放互斥量。
没有明确的谁上锁谁解锁的概念。任务可以获取任何可用的互斥量,并且可以在不同的任务之间传递互斥量。

RT-Thread中的互斥量:

在RT-Thread中,互斥量是通过 rt_mutex_take() 和 rt_mutex_release() 函数获取和释放的。
互斥量与任务关联,任务可以获取和释放它们。
实现了“谁上锁谁解锁”的功能。这意味着只有成功获取互斥量的任务才能释放它,从而确保了互斥量的所有权。
因此,RT-Thread的互斥量实现了更严格的所有权模式,

确保了只有成功获取互斥量的任务才能释放它,从而避免了可能的资源竞争和数据破坏。这种设计可以更好地管理任务之间的资源访问,提高系统的可靠性和稳定性。

总结

本篇文章主要讲解了互斥量的基本概念和基本使用,还对比了互斥量和信号量的区别,以及讲解了什么是优先级翻转,以及解决方法,并且讲解了FreeRTOS中互斥量和RT-Thread互斥量的区别。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/6717.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【4088】基于小程序实现的二手物品交易系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;spring…

pandas学习笔记11

DataFrame结构 DataFrame 一个表格型的数据结构&#xff0c;既有行标签&#xff08;index&#xff09;&#xff0c;又有列标签&#xff08;columns&#xff09;&#xff0c;它也被称异构数据表&#xff0c;所谓异构&#xff0c;指的是表格中每列的数据类型可以不同&#xff0c;…

目标检测算法YOLOv5简介

没有关于YOLOv5的直接论文&#xff0c;YOLOv5由Ultralytics维护&#xff0c;源码见&#xff1a;https://github.com/ultralytics/yolov5 &#xff0c;于2020年6月发布v1.0版本&#xff0c;最新发布版本为v7.0&#xff0c;License为AGPL-3.0. 以下内容主要来自&#xff1a; 1. U…

2024.4.29 Pandas day01 基础语法

pandas是python的一个数据库&#xff0c;在使用数据库的时候需要输入 import pandas as pd 引入&#xff0c; df pd.read.csv(文件路径“&#xff09;&#xff1a;这是利用pandas数据库读取CSV文件的方法&#xff0c;如果读取EXCEL文件或者其他文件&#xff0c;csv文件换成其他…

库存管理系统开源啦

软件介绍 ModernWMS是一个针对小型物流仓储供应链流程的开源库存管理系统。该系统的开发初衷是为了满足中小型企业在有限IT预算下对仓储管理的需求。通过总结多年ERP系统研发经验&#xff0c;项目团队开发了这套适用于中小型企业的系统&#xff0c;以帮助那些有特定需求的用户。…

Python-Socket编程实现tcp-udp通信

本文章是记录我准备大创项目时学的socket编程的用法&#xff0c;纯属记录生活&#xff0c;没有教学意义&#xff0c;视频我是看b站up主王铭东学的&#xff0c;讲的很详细&#xff0c;我只粗略学了个大概&#xff0c;我想要通过tcp&#xff0c;udp传输yolo目标检测中的物体坐标信…

C语言中的goto语句

goto label; C 语言中的 goto 语句允许把控制无条件转移到同一函数内的被标记的语句。 #include <stdio.h> int main(){goto first;printf("我是你好\n");first:printf("nihao\n");second:printf("This is 2\n");return 0; } 使用goto会…

== 和 equals()区别,equals()重写问题

对于引用类型&#xff1a;比较的是两个引用是否相同&#xff08;所指的是否为同一个对象&#xff09;&#xff0c;注&#xff1a;如果两个引用所指的对象内容一样&#xff0c;但是不是同一个对象&#xff08;hashcode不一样&#xff09;&#xff0c;依然返回false&#xff0c;随…

MYSQL数据目录结构上篇-表在文件系统中表示

前言感悟:我个人是比较不喜欢只会用,不太懂为什么的这么用,而且有的时候很多官方术 语让人难以读懂, 这里我会用比较大白话的方式,让我自己也能让网友们更加理解,如果书写哪里有误,欢迎大家指出((,,•ω•)ノ"(っω•&#xff40;。)) 从入门开始啦推荐一个学习mysql的视频…

在GPU上加速RWKV6模型的Linear Attention计算

精简版&#xff1a;经过一些profile发现flash-linear-attention中的rwkv6 linear attention算子的表现比RWKV-CUDA中的实现性能还要更好&#xff0c;然后也看到了继续优化triton版本kernel的线索。接着还分析了一下rwkv6 cuda kernel的几次开发迭代以此说明对于不懂cuda以及平时…

c++ 读取输入加速

c 在处理大规模输入输出时cin会很慢&#xff0c; 可能需要使用scanf 代码 这时候就需要使用下面的函数来加速cin 的输入 代码 static const auto io_sync_off[](){ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);return nullptr; }();使用例子 static con…

基于Springboot的房屋租赁管理系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的房屋租赁管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构…

【机器学习】Ctrl-Adapter:视频生成领域的革新者

Ctrl-Adapter&#xff1a;视频生成领域的革新者 一、ControlNets的挑战与Ctrl-Adapter的应运而生二、Ctrl-Adapter的技术原理与实现三、Ctrl-Adapter的应用实例与性能表现四、Ctrl-Adapter的意义与未来展望 随着人工智能技术的飞速发展&#xff0c;图像与视频生成领域正经历着前…

【busybox记录】【shell指令】cksum

目录 内容来源&#xff1a; 【GUN】【cksum】指令介绍 【busybox】【cksum】指令介绍 【linux】【cksum】指令介绍 使用示例&#xff1a; 计算校验和 - 传统输出格式 默认输出 - 基础POSIX标准32位CRC校验和 其他校验指令对参数有更好的支持&#xff0c;请看其他校验指…

一篇文章带你深入了解“指针”

一篇文章带你深入了解“指针” 内存和地址了解指针指针类型const修饰指针指针的运算指针与整数之间的运算指针与指针之间的运算指针的关系运算 void* 指针传值调用和传址调用数组和指针的关系野指针野指针的形成原因规避野指针 二级指针字符指针指针数组数组指针数组传参一维数…

灌溉机器人 状压dp

灌溉机器人 题目描述 农田灌溉是一项十分费体力的农活&#xff0c;特别是大型的农田。小明想为农民伯伯们减轻农作负担&#xff0c;最近在研究一款高科技——灌溉机器人。它可以在远程电脑控制下&#xff0c;给农田里的作物进行灌溉。 现在有一片 N 行 M 列的农田。农田的土…

Java Jackson-jr 库是干什么用的

Jackson-jr 是一个轻量级的Java JSON 处理库。这个库被设计用来替代 Jackson 的复杂性。对比 Jackson 的复杂 API&#xff0c;Jackson-jr 的启动速度更快&#xff0c;包大小更小。 虽然Jackson databind&#xff08;如ObjectMapper&#xff09;是通用数据绑定的良好选择&#…

三维重建(SFM)与实时定位建图(SLAM)的区分与联系

1、SLAM SLAM是Simultaneous Location and Mapping&#xff0c;同时定位与地图构建。是指搭载特定传感器的主体&#xff0c;在没有环境先验信息的情况下&#xff0c;于运动过程中建立环境的模型&#xff0c;同时估计自己的运动。目的是解决自主机器人“定位”和“建图”两个问题…

AI学习指南-学习AI需要的编程基础

亲爱的AI初学者们&#xff0c;欢迎来到人工智能的奇妙世界&#xff01;&#x1f680; 在这篇博客中&#xff0c;我将带你了解学习人工智能所需的编程基础。不用担心&#xff0c;我会尽量用简单易懂的方式来解释&#xff0c;让你即使是编程新手也能轻松上手&#xff01; 1. Pyt…

OpenCV多张图片堆叠显示

OpenCV实现多张图片堆叠显示 程序思路效果代码 程序思路 读取两张或多张图片&#xff1b;获取图片尺寸&#xff1b;选择多张图片中较大的宽度和高度建立画布&#xff1b;合并图片到画布&#xff1b; 效果 代码 import cv2 import numpy as np# 读取两张图片 img1 cv2.imrea…