RT_Thread内核机制学习(六)互斥量

news2024/11/18 23:50:44

互斥量

互斥量是特殊的信号量,资源个数只能是0、1,实现了优先级继承。
互斥量优点:谁拥有谁释放,优先级继承。

信号量的缺点:谁都可以释放信号量、优先级反转。

在这里插入图片描述
HP被MP抢占,优先级反转。

互斥量实现了优先级继承。

在这里插入图片描述
在这里插入图片描述
提升了拥有者的优先级,使其尽快释放资源。

互斥量结构体

struct rt_mutex
{
    struct rt_ipc_object parent;                        /**< inherit from ipc_object */

    rt_uint16_t          value;                         /**< value of mutex */

    rt_uint8_t           original_priority;             /**< priority of last thread hold the mutex */
    rt_uint8_t           hold;                          /**< numbers of thread hold the mutex */

    struct rt_thread    *owner;                         //信号量拥有者
};

struct rt_ipc_object
{
    struct rt_object parent;                            /**< inherit from rt_object */

    rt_list_t        suspend_thread;                    /**< threads pended on this resource */
};
rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag)
{
    struct rt_mutex *mutex;

    RT_DEBUG_NOT_IN_INTERRUPT;

    /* allocate object */
    mutex = (rt_mutex_t)rt_object_allocate(RT_Object_Class_Mutex, name); //分配互斥量结构体
    if (mutex == RT_NULL)
        return mutex;

    /* initialize ipc object */
    rt_ipc_object_init(&(mutex->parent));

    mutex->value              = 1;// 初始值设为1,表示资源可用
    mutex->owner              = RT_NULL;
    mutex->original_priority  = 0xFF;
    mutex->hold               = 0;

    /* set flag */
    mutex->parent.parent.flag = flag;

    return mutex;
}
RTM_EXPORT(rt_mutex_create);

线程第一次获取互斥量

rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
{
	 temp = rt_hw_interrupt_disable();//关中断
	 if (mutex->value > 0)
        {
            /* mutex is available */
            mutex->value --;

            /* set mutex owner and original priority */
            mutex->owner             = thread;
            mutex->original_priority = thread->current_priority;
            mutex->hold ++;
        }
    rt_hw_interrupt_enable(temp);
    return RT_EOK;
}

线程第二次获取互斥量,同一个线程可以多次获取

rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
{
	temp = rt_hw_interrupt_disable();//关中断
	if (mutex->owner == thread)
    {
        /* it's the same thread */
        mutex->hold ++;
    }
    rt_hw_interrupt_enable(temp);
    return RT_EOK;
}

不同线程获取互斥量

rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time)
{
	temp = rt_hw_interrupt_disable();//关中断
	if (thread->current_priority < mutex->owner->current_priority)//如果当前因申请互斥量而被阻塞的线程的优先级高于拥有互斥量的优先级
                {
                    /* change the owner thread priority */
                    rt_thread_control(mutex->owner,
                                      RT_THREAD_CTRL_CHANGE_PRIORITY,
                                      &thread->current_priority);//占有线程的优先级继承线程的优先级
                }
    

}

释放互斥量


/**
 * This function will release a mutex, if there are threads suspended on mutex,
 * it will be waked up.
 *
 * @param mutex the mutex object
 *
 * @return the error code
 */
rt_err_t rt_mutex_release(rt_mutex_t mutex)
{
	if (thread != mutex->owner)
    {
        thread->error = -RT_ERROR;

        /* enable interrupt */
        rt_hw_interrupt_enable(temp);

        return -RT_ERROR;
    }
	mutex->hold --;//释放一次
	if (mutex->hold == 0)
    {
        /* change the owner thread to original priority */
        if (mutex->original_priority != mutex->owner->current_priority)//如果线程原始优先级和当前优先级不一样,一定发生了优先级继承,所以需要恢复优先级
        {
            rt_thread_control(mutex->owner,
                              RT_THREAD_CTRL_CHANGE_PRIORITY,
                              &(mutex->original_priority));
        }

        /* wakeup suspended thread */
        if (!rt_list_isempty(&mutex->parent.suspend_thread))
        {
            /* get suspended thread */
            thread = rt_list_entry(mutex->parent.suspend_thread.next,
                                   struct rt_thread,
                                   tlist);

            RT_DEBUG_LOG(RT_DEBUG_IPC, ("mutex_release: resume thread: %s\n",
                                        thread->name));

            /* set new owner and priority */
            mutex->owner             = thread;
            mutex->original_priority = thread->current_priority;
            mutex->hold ++;

            /* resume thread */
            rt_ipc_list_resume(&(mutex->parent.suspend_thread));

            need_schedule = RT_TRUE;
        }
        else
        {
            /* increase value */
            mutex->value ++;

            /* clear owner */
            mutex->owner             = RT_NULL;
            mutex->original_priority = 0xff;
        }
    }
}

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

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

相关文章

MySQL备份和还原

前言 mysql日志默认保存在/usr/local/mysql/data 常见的日志&#xff1a; 1、错误日志 2、一般查询日志 3、二进制日志 4、中继日志 5、重做日志 6、回滚日志 7、慢查询日志 配置文件位置 vim /etc/my.cnf 错误日志&#xff0c;用来记录当MySQL启动、停止或运行时发生的错误信…

Java 数据结构使用学习

Set和List的区别 Set 接口实例存储的是无序的&#xff0c;不重复的数据。List 接口实例存储的是有序的&#xff0c;可以重复的元素。 Set 检索效率低下&#xff0c;删除和插入效率高&#xff0c;插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。 List 和数…

Linux-crontab使用问题解决

添加定时进程 终端输入&#xff1a; crontab -e选择文本编辑方式&#xff0c;写入要运行的脚本&#xff0c;以及时间要求。 注意&#xff0c;如果有多个运行指令分两种情况&#xff1a; 1.多个运行指令之间没有耦合关系&#xff0c;分别独立&#xff0c;则可以直接分为两个…

C++学习记录——이십구 异常

文章目录 1、异常概念2、实际用法3、C标准库的异常体系4、重新抛出异常5、优缺点 1、异常概念 C语言处理错误有assert&#xff0c;返回错误码来处理错误的方式&#xff0c;不过release模式下assert无效&#xff0c;错误码需要程序员自己去查看是什么错误。 C认为应当能给到程…

LLMs之Code:Code Llama的简介、安装、使用方法之详细攻略

LLMs之Code&#xff1a;Code Llama的简介、安装、使用方法之详细攻略 导读&#xff1a;2023年08月25日(北京时间)&#xff0c;Meta发布了Code Llama&#xff0c;一个可以使用文本提示生成代码的大型语言模型(LLM)。Code Llama是最先进的公开可用的LLM代码任务&#xff0c;并有潜…

会玩这10个Linux命令,一定是个有趣的IT男!

Linux当中有很多比较有趣的命令&#xff0c;可以动手看看&#xff0c;很简单的。 1、rev命令 一行接一行地颠倒所输入的字符串。 运行&#xff1a; $rev 如输入&#xff1a;shiyanlou shiyanlou 2、asciiview命令 1)先安装aview $sudo apt-get install aview 2)再安装…

第八周第二天学习总结 | MySQL入门及练习学习第四天

实操练习&#xff1a; 1.建立一个员工表和与之对应的部门表 2.建立外键约束 3.使用多表查询&#xff0c;直接查询部门表和员工表 发现&#xff1a;有很多多余的因笛卡尔乘积而带来的多余输出内容 我想要的到简单明了的数据结果&#xff0c;要消除多于因笛卡尔乘积带来的输出…

3d激光slam建图与定位(2)_aloam代码阅读

1.常用的几种loam算法 aloam 纯激光 lego_loam 纯激光 去除了地面 lio_sam imu激光紧耦合 lvi_sam 激光视觉 2.代码思路 2.1.特征点提取scanRegistration.cpp&#xff0c;这个文件的目的是为了根据曲率提取4种特征点和对当前点云进行预处理 输入是雷达点云话题 输出是 4种特征点…

【Apollo学习笔记】——规划模块TASK之PATH_ASSESSMENT_DECIDER

文章目录 前言PATH_ASSESSMENT_DECIDER功能简介PATH_ASSESSMENT_DECIDER相关信息PATH_ASSESSMENT_DECIDER总体流程1. 去除无效路径2. 分析并加入重要信息给speed决策SetPathInfoSetPathPointType 3. 排序选择最优的路径4. 更新必要的信息 前言 在Apollo星火计划学习笔记——Ap…

信息系统项目管理师(第四版)教材精读思维导图-第七章项目立项管理

请参阅我的另一篇文章&#xff0c;综合介绍软考高项&#xff1a; 信息系统项目管理师&#xff08;软考高项&#xff09;备考总结_计算机技术与软件专业技术_铭记北宸的博客-CSDN博客 本章思维导图PDF格式 本章思维导图XMind源文件 ​ 目录 7.1 项目建议与立项申请 7.2 项目可…

【洛谷】P1873 EKO / 砍树

原题链接&#xff1a;https://www.luogu.com.cn/problem/P1873 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 整体思路&#xff1a;二分答案 设置一个变量highest来记录最高的树的高度&#xff0c;sum记录切下的木头的长度。令左边界l0&#xff0c…

java八股文面试[多线程]——公平锁

一个线程启动时刚好碰到另外的线程释放锁&#xff0c;则该线程会获取到锁&#xff0c;其他等待队列中的线程不会获取到锁。好处&#xff1a;减少线程状态切换&#xff08;不用在start()之后进入阻塞&#xff09;&#xff0c;提高吞吐量。 非公平锁 非公平锁是多个线程加锁时直接…

高通开发系列 - QTI守护进程服务介绍

By: fulinux E-mail: fulinux@sina.com Blog: https://blog.csdn.net/fulinus 喜欢的盆友欢迎点赞和订阅! 你的喜欢就是我写作的动力! 返回:专栏总目录 目录 代码位置和依赖关系功能介绍代码逻辑讲解外设节点关注的目录socket服务端初始化DPM客户端监听守护关键的数据结构体…

C# char曲线控件

一、char曲线显示随机数数据 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using Syst…

【JS案例】JS实现手风琴效果

JS案例手风琴 &#x1f31f;效果展示 &#x1f31f;HTML结构 &#x1f31f;CSS样式 &#x1f31f;实现思路 &#x1f31f;具体实现 1.绑定事件 2.自定义元素属性 3.切换菜单 &#x1f31f;完整JS代码 &#x1f31f;写在最后 &#x1f31f;效果展示 &#x1f31f;HTML…

如何使用pytest进行自动化测试

Pytest作为广泛使用的Python测试框架之一&#xff0c;可以用于单元测试、功能测试、性能测试等场合。自动化测试是功能测试的一种形式&#xff0c;可以使用Pytest编写并管理自动化测试用例&#xff0c;再执行相应的自动化测试。 功能测试通常包括接口测试和Web测试两种类型&am…

服务器端使用django websocket,客户端使用uniapp 请问服务端和客户端群组互发消息的代码怎么写的参考笔记

2023/8/29 19:21:11 服务器端使用django websocket,客户端使用uniapp 请问服务端和客户端群组互发消息的代码怎么写 2023/8/29 19:22:25 在服务器端使用Django WebSocket和客户端使用Uniapp的情况下&#xff0c;以下是代码示例来实现服务器端和客户端之间的群组互发消息。 …

使用GoLand进行远程调试

对部署进行配置 在此配置远程服务器地址&#xff0c;映射&#xff0c;是否自动上传(更新)等 选择SFTP类型 选择上传 另外给自动上传选项打钩 此时在本地修改某个文件&#xff0c;远程机器相应目录的文件&#xff0c;也会被同步修改 对远程调试进行配置 远程机器需要安装delve 而…

桃子叶片病害识别(图像连续识别和视频识别,Python代码,pyTorch框架,深度卷积网络模型,很容易替换为其它模型,带有GUI识别界面)

桃子叶片病害识别&#xff08;图像连续识别和视频识别&#xff0c;Python代码&#xff0c;pyTorch框架&#xff0c;深度卷积网络模型&#xff0c;很容易替换为其它模型&#xff0c;带有GUI识别界面&#xff09;_哔哩哔哩_bilibili 1.数据集分为三类 健康的桃子叶片 &#xff0c…

LeetCode(力扣)530. 二叉搜索树的最小绝对差Python

LeetCode530. 二叉搜索树的最小绝对差 题目链接代码 题目链接 https://leetcode.cn/problems/minimum-absolute-difference-in-bst/ 代码 递归 # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # …