互斥量的使用

news/2024/9/24 16:28:57/
cle class="baidu_pl">
cle_content" class="article_content clearfix">
content_views" class="markdown_views prism-atom-one-light">cap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);">

class="toc">

文章目录

  • 前言
  • 一、互斥量与二进制信号量
  • 二、优先级反转与优先级继承
  • 三、递归锁


前言

通过学习上一章互斥量理论基础࿰c;这一章我们来做一些实验进行验证。


一、互斥量与二进制信号量

ckquote>

互斥量使用和二进制信号量类似

ckquote>
  1. 互斥量有优先级继承功能࿰c;二进制信号量没有
  2. Give/Take函数完全一样
  3. 二进制信号量的初始值是0࿰c;互斥量的初始值是1

二、优先级反转与优先级继承

ckquote>

首先创建三个优先级不同的任务

ckquote>
<code class="prism language-cpp">		class="token function">xTaskCreateclass="token punctuation">( vLPTaskclass="token punctuation">, class="token string">"LPTask"class="token punctuation">, class="token number">1000class="token punctuation">, class="token constant">NULLclass="token punctuation">, class="token number">1class="token punctuation">, class="token constant">NULL class="token punctuation">)class="token punctuation">;class="token function">xTaskCreateclass="token punctuation">( vMPTaskclass="token punctuation">, class="token string">"MPTask"class="token punctuation">, class="token number">1000class="token punctuation">, class="token constant">NULLclass="token punctuation">, class="token number">2class="token punctuation">, class="token constant">NULL class="token punctuation">)class="token punctuation">;class="token function">xTaskCreateclass="token punctuation">( vHPTaskclass="token punctuation">, class="token string">"HPTask"class="token punctuation">, class="token number">1000class="token punctuation">, class="token constant">NULLclass="token punctuation">, class="token number">3class="token punctuation">, class="token constant">NULL class="token punctuation">)class="token punctuation">;
code>
ckquote>

创建互斥量/二进制信号量

ckquote>
<code class="prism language-cpp">SemaphoreHandle_t xLockclass="token punctuation">;
class="token comment">//    xLock = xSemaphoreCreateBinary( );xLock class="token operator">= class="token function">xSemaphoreCreateMutexclass="token punctuation">( class="token punctuation">)class="token punctuation">;class="token function">xSemaphoreGiveclass="token punctuation">(xLockclass="token punctuation">)class="token punctuation">;
code>
ckquote>

三个优先级不同的任务处理不同事情࿰c;验证二进制信号量优先级反转互斥量优先级继承功能

ckquote>
<code class="prism language-cpp">class="token comment">/*-----------------------------------------------------------*/
class="token keyword">static class="token keyword">void class="token function">vLPTaskclass="token punctuation">( class="token keyword">void class="token operator">*pvParameters class="token punctuation">)
class="token punctuation">{class="token keyword">const TickType_t xTicksToWait class="token operator">= class="token function">pdMS_TO_TICKSclass="token punctuation">( class="token number">10UL class="token punctuation">)class="token punctuation">;	class="token keyword">uint32_t iclass="token punctuation">;class="token keyword">char c class="token operator">= class="token char">'A'class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"LPTask start\r\n"class="token punctuation">)class="token punctuation">;class="token comment">/* 无限循环 */class="token keyword">forclass="token punctuation">( class="token punctuation">;class="token punctuation">; class="token punctuation">)class="token punctuation">{	flagLPTaskRun class="token operator">= class="token number">1class="token punctuation">;flagMPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagHPTaskRun class="token operator">= class="token number">0class="token punctuation">;class="token comment">/* 获得互斥量/二进制信号量 */class="token function">xSemaphoreTakeclass="token punctuation">(xLockclass="token punctuation">, portMAX_DELAYclass="token punctuation">)class="token punctuation">;class="token comment">/* 耗时很久 */class="token function">printfclass="token punctuation">(class="token string">"LPTask take the Lock for long time"class="token punctuation">)class="token punctuation">;class="token keyword">for class="token punctuation">(i class="token operator">= class="token number">0class="token punctuation">; i class="token operator">< class="token number">26class="token punctuation">; iclass="token operator">++class="token punctuation">) class="token punctuation">{flagLPTaskRun class="token operator">= class="token number">1class="token punctuation">;flagMPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagHPTaskRun class="token operator">= class="token number">0class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"%c"class="token punctuation">, c class="token operator">+ iclass="token punctuation">)class="token punctuation">;class="token punctuation">}class="token function">printfclass="token punctuation">(class="token string">"\r\n"class="token punctuation">)class="token punctuation">;class="token comment">/* 释放互斥量/二进制信号量 */class="token function">xSemaphoreGiveclass="token punctuation">(xLockclass="token punctuation">)class="token punctuation">;class="token function">vTaskDelayclass="token punctuation">(xTicksToWaitclass="token punctuation">)class="token punctuation">;class="token punctuation">}
class="token punctuation">}class="token keyword">static class="token keyword">void class="token function">vMPTaskclass="token punctuation">( class="token keyword">void class="token operator">*pvParameters class="token punctuation">)
class="token punctuation">{class="token keyword">const TickType_t xTicksToWait class="token operator">= class="token function">pdMS_TO_TICKSclass="token punctuation">( class="token number">30UL class="token punctuation">)class="token punctuation">;	flagLPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagMPTaskRun class="token operator">= class="token number">1class="token punctuation">;flagHPTaskRun class="token operator">= class="token number">0class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"MPTask start\r\n"class="token punctuation">)class="token punctuation">;class="token comment">/* 让LPTask、HPTask先运行 */	class="token function">vTaskDelayclass="token punctuation">(xTicksToWaitclass="token punctuation">)class="token punctuation">;class="token comment">/* 无限循环 */class="token keyword">forclass="token punctuation">( class="token punctuation">;class="token punctuation">; class="token punctuation">)class="token punctuation">{	flagLPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagMPTaskRun class="token operator">= class="token number">1class="token punctuation">;flagHPTaskRun class="token operator">= class="token number">0class="token punctuation">;class="token punctuation">}
class="token punctuation">}class="token keyword">static class="token keyword">void class="token function">vHPTaskclass="token punctuation">( class="token keyword">void class="token operator">*pvParameters class="token punctuation">)
class="token punctuation">{class="token keyword">const TickType_t xTicksToWait class="token operator">= class="token function">pdMS_TO_TICKSclass="token punctuation">( class="token number">10UL class="token punctuation">)class="token punctuation">;	flagLPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagMPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagHPTaskRun class="token operator">= class="token number">1class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"HPTask start\r\n"class="token punctuation">)class="token punctuation">;class="token comment">/* 让LPTask先运行 */	class="token function">vTaskDelayclass="token punctuation">(xTicksToWaitclass="token punctuation">)class="token punctuation">;class="token comment">/* 无限循环 */class="token keyword">forclass="token punctuation">( class="token punctuation">;class="token punctuation">; class="token punctuation">)class="token punctuation">{	flagLPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagMPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagHPTaskRun class="token operator">= class="token number">1class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"HPTask wait for Lock\r\n"class="token punctuation">)class="token punctuation">;class="token comment">/* 获得互斥量/二进制信号量 */class="token function">xSemaphoreTakeclass="token punctuation">(xLockclass="token punctuation">, portMAX_DELAYclass="token punctuation">)class="token punctuation">;flagLPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagMPTaskRun class="token operator">= class="token number">0class="token punctuation">;flagHPTaskRun class="token operator">= class="token number">1class="token punctuation">;class="token comment">/* 释放互斥量/二进制信号量 */class="token function">xSemaphoreGiveclass="token punctuation">(xLockclass="token punctuation">)class="token punctuation">;class="token punctuation">}
class="token punctuation">}class="token comment">/*-----------------------------------------------------------*/
code>
ckquote>

二进制信号量 实现优先级反转࿰c;中优先级先于高优先级执行

ckquote>

c="https://img-blog.csdnimg.cn/direct/fc84a435d25540c58d35ee3fa01edb4c.png" alt="在这里插入图片描述" />

ckquote>

互斥量实现优先级继承

ckquote>

c="https://img-blog.csdnimg.cn/direct/e4a3e59d69d4435a810417298fa385ee.png" alt="在这里插入图片描述" />

三、递归锁

ckquote>

创建递归锁

ckquote>
<code class="prism language-cpp">class="token comment">/* 递归锁句柄 */
SemaphoreHandle_t xMutexclass="token punctuation">;xMutex class="token operator">= class="token function">xSemaphoreCreateRecursiveMutexclass="token punctuation">( class="token punctuation">)class="token punctuation">;
code>
ckquote>

创建2个任务: 一个上锁, 另一个自己监守自盗(开别人的锁自己用)

ckquote>
<code class="prism language-cpp">		class="token function">xTaskCreateclass="token punctuation">( vTakeTaskclass="token punctuation">, class="token string">"Task1"class="token punctuation">, class="token number">1000class="token punctuation">, class="token constant">NULLclass="token punctuation">, class="token number">2class="token punctuation">, class="token constant">NULL class="token punctuation">)class="token punctuation">;class="token function">xTaskCreateclass="token punctuation">( vGiveAndTakeTaskclass="token punctuation">, class="token string">"Task2"class="token punctuation">, class="token number">1000class="token punctuation">, class="token constant">NULLclass="token punctuation">, class="token number">1class="token punctuation">, class="token constant">NULL class="token punctuation">)class="token punctuation">;class="token comment">/* 启动调度器 */class="token function">vTaskStartSchedulerclass="token punctuation">(class="token punctuation">)class="token punctuation">;
code>
ckquote>

任务描述

ckquote>
<code class="prism language-cpp">class="token comment">/*-----------------------------------------------------------*/
class="token keyword">static class="token keyword">void class="token function">vTakeTaskclass="token punctuation">( class="token keyword">void class="token operator">*pvParameters class="token punctuation">)
class="token punctuation">{class="token keyword">const TickType_t xTicksToWait class="token operator">= class="token function">pdMS_TO_TICKSclass="token punctuation">( class="token number">100UL class="token punctuation">)class="token punctuation">;	BaseType_t xStatusclass="token punctuation">;class="token keyword">int iclass="token punctuation">;class="token comment">/* 无限循环 */class="token keyword">forclass="token punctuation">( class="token punctuation">;class="token punctuation">; class="token punctuation">)class="token punctuation">{	class="token comment">/* 获得递归锁: 上锁 */xStatus class="token operator">= class="token function">xSemaphoreTakeRecursiveclass="token punctuation">(xMutexclass="token punctuation">, portMAX_DELAYclass="token punctuation">)class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"Task1 take the Mutex in main loop %s\r\n"class="token punctuation">, \class="token punctuation">(xStatus class="token operator">== pdTRUEclass="token punctuation">)class="token operator">? class="token string">"Success" class="token operator">: class="token string">"Failed"class="token punctuation">)class="token punctuation">;class="token comment">/* 阻塞很长时间, 让另一个任务执行, * 看看它有无办法再次获得递归锁 */class="token function">vTaskDelayclass="token punctuation">(xTicksToWaitclass="token punctuation">)class="token punctuation">;class="token keyword">for class="token punctuation">(i class="token operator">= class="token number">0class="token punctuation">; i class="token operator">< class="token number">10class="token punctuation">; iclass="token operator">++class="token punctuation">)class="token punctuation">{class="token comment">/* 获得递归锁: 上锁 */xStatus class="token operator">= class="token function">xSemaphoreTakeRecursiveclass="token punctuation">(xMutexclass="token punctuation">, portMAX_DELAYclass="token punctuation">)class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"Task1 take the Mutex in sub loop %s, for time %d\r\n"class="token punctuation">, \class="token punctuation">(xStatus class="token operator">== pdTRUEclass="token punctuation">)class="token operator">? class="token string">"Success" class="token operator">: class="token string">"Failed"class="token punctuation">, iclass="token punctuation">)class="token punctuation">;class="token comment">/* 释放递归锁 */class="token function">xSemaphoreGiveRecursiveclass="token punctuation">(xMutexclass="token punctuation">)class="token punctuation">;class="token punctuation">}class="token comment">/* 释放递归锁 */class="token function">xSemaphoreGiveRecursiveclass="token punctuation">(xMutexclass="token punctuation">)class="token punctuation">;class="token punctuation">}
class="token punctuation">}class="token keyword">static class="token keyword">void class="token function">vGiveAndTakeTaskclass="token punctuation">( class="token keyword">void class="token operator">*pvParameters class="token punctuation">)
class="token punctuation">{class="token keyword">const TickType_t xTicksToWait class="token operator">= class="token function">pdMS_TO_TICKSclass="token punctuation">( class="token number">10UL class="token punctuation">)class="token punctuation">;	BaseType_t xStatusclass="token punctuation">;class="token comment">/* 尝试获得递归锁: 上锁 */xStatus class="token operator">= class="token function">xSemaphoreTakeRecursiveclass="token punctuation">(xMutexclass="token punctuation">, class="token number">0class="token punctuation">)class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"Task2: at first, take the Mutex %s\r\n"class="token punctuation">, \class="token punctuation">(xStatus class="token operator">== pdTRUEclass="token punctuation">)class="token operator">? class="token string">"Success" class="token operator">: class="token string">"Failed"class="token punctuation">)class="token punctuation">;class="token comment">/* 如果失败则监守自盗: 开锁 */class="token keyword">if class="token punctuation">(xStatus class="token operator">!= pdTRUEclass="token punctuation">)class="token punctuation">{class="token comment">/* 无法释放别人持有的锁 */xStatus class="token operator">= class="token function">xSemaphoreGiveRecursiveclass="token punctuation">(xMutexclass="token punctuation">)class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"Task2: give Mutex %s\r\n"class="token punctuation">, \class="token punctuation">(xStatus class="token operator">== pdTRUEclass="token punctuation">)class="token operator">? class="token string">"Success" class="token operator">: class="token string">"Failed"class="token punctuation">)class="token punctuation">;class="token punctuation">}class="token comment">/* 如果无法获得, 一直等待 */xStatus class="token operator">= class="token function">xSemaphoreTakeRecursiveclass="token punctuation">(xMutexclass="token punctuation">, portMAX_DELAYclass="token punctuation">)class="token punctuation">;class="token function">printfclass="token punctuation">(class="token string">"Task2: and then, take the Mutex %s\r\n"class="token punctuation">, \class="token punctuation">(xStatus class="token operator">== pdTRUEclass="token punctuation">)class="token operator">? class="token string">"Success" class="token operator">: class="token string">"Failed"class="token punctuation">)class="token punctuation">;class="token comment">/* 无限循环 */class="token keyword">forclass="token punctuation">( class="token punctuation">;class="token punctuation">; class="token punctuation">)class="token punctuation">{	class="token comment">/* 什么都不做 */class="token function">vTaskDelayclass="token punctuation">(xTicksToWaitclass="token punctuation">)class="token punctuation">;class="token punctuation">}
class="token punctuation">}
class="token comment">/*-----------------------------------------------------------*/code>
ckquote>

结果

ckquote>

c="https://img-blog.csdnimg.cn/direct/6c8352acc2ef4236bea49642f59195b0.png" alt="在这里插入图片描述" />


http://www.ppmy.cn/news/1455897.html

相关文章

js api part4

其他事件 页面加载事件 外部资源&#xff08;如图片、外联CSS和JavaScript等&#xff09;加载完毕时触发的事件 原因&#xff1a;有些时候需要等页面资源全部处理完了做一些事情&#xff0c;老代码喜欢把 script 写在 head 中&#xff0c;这时候直接找 dom 元素找不到。 事件…

Linux 磁盘管理命令fdisk mount umount mkfs mkfs.ext2

文章目录 3.Linux 磁盘管理命令3.4 fdisk&#xff1a;磁盘分区案例练习 3.5 mount&#xff1a;挂载文件系统案例练习 3.6 umount&#xff1a;卸载文件系统案例练习 3.7 mkfs&#xff1a;建立各种文件系统案例练习 3.8 mkfs.ext2&#xff1a;建立一个 Ext2/Ext3 文件系统案例练习…

虚拟键代码

虚拟键代码 虚拟键码 (Winuser.h) - Win32 apps | Microsoft Learn 在Windows操作系统中&#xff0c;虚拟键代码&#xff08;Virtual-Key Codes&#xff09;是一组用来表示键盘上按键的数值。这些代码通常用于Windows API函数&#xff0c;以便程序能够识别和处理键盘输入。 虚拟…

【论文阅读】 Loss Functions for Image Restoration with Neural Networks

Loss Functions for Image Restoration with Neural Networks 论文地址摘要I. 引言II 相关工作用于图像恢复的神经网络B 找到更好的解决方案。 三、图像恢复的损失层A. l1 错误 The l1 ErrorB. SSIMC. MS-SSIMD. The Best of Both Worlds: MS-SSIM L1 四、结果A. Joint Denois…

[Flutter]单元测试和组件测试

1.单元测试 在Flutter开发中&#xff0c;进行单元测试是确保你的代码质量以及未来更改不会破坏现有功能的关键步骤。当你开发私有包时&#xff0c;单元测试尤其重要&#xff0c;因为这有助于保持包的稳定性和可维护性。以下是如何在Flutter中进行单元测试的详细指南&#xff1…

五、VGA 叠加图像原理和实现(十字光标)

前言&#xff1a;该案例在VGA项目&#xff1a;联合精简帧双fifosobel算法 实现VGA显示项目的基础上进行改动。 要求&#xff1a;通过串口助手把 198x198 的十字光标图像二进制数据传递给 FPGA 板卡&#xff0c;FPGA 板 卡接收到后存储到 Ram 中用于 VGA 叠加显示。 预期效果展…

ISIS的基本概念

1.ISIS概述 IS-IS是一种链路状态路由协议&#xff0c;IS-IS与OSPF在许多方面非常相似&#xff0c; 例如运行IS-IS协议的直连设备之间通过发送Hello报文发现彼此&#xff0c;然后建立邻接关系&#xff0c;并交互链路状态信息。 CLNS由以下三个部分组成&#xff1a; CLNP&#xf…

3.栈和队列(汇总版)

目录 1.栈&#xff08;一端插和删&#xff09; 2.队列&#xff08;一端插另一段删&#xff09; 2.1队列的概念及结构 2.2 队列的实现 队列的接口 1.初始化队列 2.销毁队列 3.插入元素 4.出队列&#xff08;头删&#xff09; 5.访问对头 6.访问队尾 7.判断队列是否为…