首页 > 其他分享 >FreeRTOS 体验教程:3.如何用互斥量实现FreeRTOS多线程访问共享资源?

FreeRTOS 体验教程:3.如何用互斥量实现FreeRTOS多线程访问共享资源?

时间:2024-06-18 15:28:21浏览次数:27  
标签:优先级 FreeRTOS 互斥 任务 切换 访问共享 多线程

FreeRTOS 互斥量使用教程

互斥量(Mutex)是一种特殊的信号量,用于管理对共享资源的访问。在 FreeRTOS 中,互斥量的句柄类型依然是 xSemaphoreHandle。本文将详细介绍如何在 FreeRTOS 中创建和使用互斥量,并通过实例展示其运行效果。

1. 创建互斥量

在 FreeRTOS 中,创建互斥量非常简单。您只需调用 xSemaphoreCreateMutex 函数即可完成。这一函数将返回一个互斥量的句柄,用于后续的操作。
image.png

void createMutex(void)
{
	if (semaphrHandle == NULL)
	{
		semaphrHandle = xSemaphoreCreateMutex();
	}
}

2. 使用互斥量

在访问共享资源前,任务需要获取互斥量。如果互斥量已经被其他任务获取,则当前任务会被阻塞,直到互斥量被释放。

以下示例展示了三个任务如何使用互斥量来管理对共享资源的访问:
创建任务 1 及任务 3 :
image.png

创建任务 2 :
image.png

3. 运行结果

在上述示例中,假设任务 2 的优先级最高,任务 1 和任务 3 的优先级相同且低于任务 2。运行结果可能会显示大部分时间都是任务 2 在输出信息:
image.png

这是因为任务 2 的优先级最高,它在释放互斥量后立即又能获取到,导致其他两个任务无法访问共享资源。

修改:增加时间片切换或阻塞

为了避免任务 1 和任务 3 饿死,可以在任务 2 释放互斥量后增加一个切换时间片或进入阻塞状态。
任务 2 使用 vTaskDelay 阻塞状态:
image.png

任务 1 和 3 使用 taskTIELD 切换任务:
image.png

4. 验证结果

通过上述修改,可以看到任务 2 仍然是最常被系统调度运行的,但任务 1 和任务 3 也能够偶尔获取到互斥量并输出信息:
image.png

这是因为任务 2 的优先级高,所以它仍然被频繁调度。然而,由于增加了时间片切换,任务 1 和任务 3 也能被系统调度。根据 FreeRTOS 的官方文档,优先级相同的任务在调度时会优先选择等待时间较长的任务,从而确保公平性。

通过合理使用互斥量和时间片切换,您可以有效避免任务饿死问题,并实现多任务的公平调度。

对应的 demo 源码, 请点击 RtosExPro at freertos_sync_metux

也可扫码关注博主同名公众号"不解之榬",回复 “freeRTOS” 获取
不解之榬


希望这篇教程对您有所帮助。如果有任何疑问或需要进一步的指导,请在评论区留言,我会尽快回复。

祝您开发顺利,代码无忧!

标签:优先级,FreeRTOS,互斥,任务,切换,访问共享,多线程
From: https://blog.csdn.net/LT450196683/article/details/139728400

相关文章

  • 面经梳理-java多线程同步协作
    题目Synchronized和ReentryLock锁锁可以视作访问共享数据的许可证。锁能够保护共享数据以实现线程安全,其作用包括保障原子性、保障可见性和保障有序性。Java平台中的锁包括内部锁(IntrinsicLock)和显式锁(ExplicitLock)。内部锁是通过synchronized关键字实现的;显式锁是通过java.ut......
  • 面经梳理-java多线程其他
    题目Threadlocal使用场景?原理?如何保证内存不泄露?ThreadLocal使用场景不加锁的情况下,多线程安全访问共享变量,每个线程保留共享变量的副本(线程特有对象),每个线程往这个ThreadLocal中读写是线程隔离。ThreadLocal原理Thread类有一个类型为ThreadLocal.ThreadLocalMap的实例变量th......
  • 面经梳理-java多线程基础
    题目线程和进程的概念?守护线程是干什么的?常见的守护线程有哪些?线程和进程的概念进程是程序的运行实例,是程序向操作系统申请资源的基本单位,线程是进程的一条执行路径。Java的线程分为两种:用户线程和守护线程。守护线程作用是为其他线程提供服务,如果所有的用户线程死亡,后台线程......
  • FreeRTOS简单内核实现6 优先级
    0、思考与回答0.1、思考一如何实现RTOS内核支持多优先级?因为不支持优先级,所以所有的任务都插入了一个名为pxReadyTasksLists的就绪链表中,相当于所有任务的优先级都是一致的,那如果我们创建一个就绪链表数组,数组下标代表优先级,优先级为x的任务就插入到pxReadyTasksLists[x......
  • FreeRTOS简单内核实现5 阻塞延时
    0、思考与回答0.1、思考一为什么FreeRTOS简单内核实现3任务管理文章中实现的RTOS内核不能看起来并行运行呢?Task1延时100ms之后执行taskYIELD()切换到Task2,Task2延时500ms之后执行taskYIELD()再次切换Task1,在延时期间两个任务均占用MCU,所以只能一个任务执行......
  • 多线程-信号量
     ManualResetEvent的用法初始化:创建一个ManualResetEvent实例,并设置其初始状态。通常,初始状态可以设置为false(表示事件尚未发生)或true(表示事件已经发生)。例如:ManualResetEventmre=newManualResetEvent(false);等待事件:在需要等待事件发生的线程中,调用WaitOne()方法......
  • 多线程处理
    基础知识阻塞与非阻塞阻塞状态指程序未得到所需计算资源时被挂起的状态。程序在等待某操作的过程中,自身不被阻塞,可以继续运行干别的事情,则称该程序在该操作上是非阻塞的。同步与异步不同程序单元为了完成某个任务,在执行过程中需靠某种通信方式以协调一致。例如在购物系统中更......
  • 【JavaEE精炼宝库】多线程(6)线程池
    目录一、线程池的概念及优势1.1线程池的概念:1.2线程池的优势:二、工厂模式三、标准库中的线程池3.1标准库线程池参数解释:3.1.1corePoolSize|maximumPoolSize:3.1.2keepAliveTime|unit:3.1.3workQueue: 3.1.4ThreadFactory: 3.1.5handler:3.2创建线程池演......
  • [转]32th@深入解析C++并发编程:从多线程到现代C++并发库@20240616
    深入解析C++并发编程:从多线程到现代C++并发库你有没有想过,为什么C++在多线程并发编程方面如此强大?C++11标准的发布,为并发编程带来了哪些革命性的变化?本文将深入探讨C++并发编程背后的技术原理,带你领略现代C++并发库的强大之处。文章将结合代码片段,为你揭示C++并发编程的精髓。1.......
  • JAVA多线程实现的三种方式
    1.继承Thread类classExtendThreadextendsThread{//继承自ThreadprivateStringname;publicExtendThread(Stringname){this.name=name;}@Overridepublicvoidrun(){//必须重写run方法,并......