0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

互斥锁不能在中断中使用?

冬至子 来源:ITRelief 作者:Sachefgh Xu 2023-07-25 15:36 次阅读

互斥锁的概念

互斥锁是一种特殊的二值信号量,因为它解决了优先级翻转的问题。可以通过优先级继承机制来解决:当另外一个的任务试图获取同一个互斥锁时,已经获得互斥锁的任务将继承该任务的优先级。

互斥锁有一个比较明显的特点,即它必须哪一个线程申请,就由该线程来释放。而在二值信号量中,释放和获取token的线程可以不一致。因此,在处理线程之间占用同一硬件资源的问题时首先考虑使用互斥锁。

API Description 【互斥锁不能在中断中使用】

①创建互斥锁

在CMSIS-RTOS中,互斥锁通过 ***osMutexNew() *** 函数和配置结构体 *osMutexAttr_t *建立。

1)配置结构体osMutexAttr_t

osMutexAttr_t 中功能参数 *attr_bits ***用于配置互斥锁的功能特性,相当重要;参数相关定义包括: **

1.* osMutexRecursive * - 创建递归互斥锁。当上锁开锁的程序段递归时,会出现多重加锁的情况,并从深处向外解锁。此时应当引入对递归的支持。本参数配置了一个递归计数机制,允许同一个线程多重加锁;调用一次计数+1,释放-1;当计数回到0时此锁解开。

2.osMutexPrioInherit - 优先级继承机制。可以防止优先级翻转。

  1. *osMutexRobust * - 互斥锁回收机制。当加锁的线程被 osThreadExit() 或 *osThreadTerminate() *终止而未能解锁时,锁将会自动回收。

上述三个参数可以通过逻辑或( | )组合传入结构体。

typedef struct {
  const char                   *name;   ///名称,仅标识用
  uint32_t                 attr_bits;   ///功能参数;重要
  void                       *cb_mem;   /// memory for control block;Default ==NULL
  uint32_t                   cb_size;   /// Default==0U
} osMutexAttr_t;

@param    attr_bits:  -参数配置;可通过逻辑或 输入复数的参数
        / osMutexPrioInherit  -使用优先级继承
        / osMutexRecursive    -递归互斥锁
        / osMutexRobust       -自回收;当线程终止时自动释放持有的token
  1. 通过 ***osMutexNew() ***创建目标互斥锁
osMutexId_t osMutexNew (const osMutexAttr_t *attr);/*创建互斥锁
@param    *attr    -osMutexAttr_t互斥锁配置结构体
@retval    -句柄(地址)
            ==NULL   创建失败*/

**②删除互斥锁 **osMutexDelete()

osStatus_t osMutexDelete( osMutexId_t  mutex_id );/*删除互斥锁
@retval:    -osOK //成功
            -osErrorParameter: parameter mutex_id is NULL or invalid.
            -osErrorResource: the mutex is in an invalid state.(其他错误)
            -osErrorISR: 在中断调用导致的错误
*/

③获取互斥锁token osMutexAcquire()

互斥锁token的获取与二值信号量基本一致。 线程调用该函数时,当锁中无token时,线程进入BLOCK状态等待消息量被放入token;。在此期间当任务检测到消息量放入token时,将自动由****BLOCK态转移为READY态。当等待的时间超过了指定的阻塞时间,即使队列中尚无数据,任务也会自动从阻塞态转移为READY态。此时程序会返回osErrorTimeout错误。若没有设置阻塞超时且参数正确,返回osErrorResource错误**。**

osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout);/*取得token;
@param      timeout      阻塞等待时间
@retval    -osOK: the mutex has been obtained.
           -osErrorTimeout: the mutex could not be obtained in the given time.
           -osErrorResource: the mutex could not be obtained when no timeout was specified.
           -osErrorParameter: parameter mutex_id is NULL or invalid.
           -osErrorISR: cannot be called from interrupt service routines.
*/

timeout参数:

== 0U //不设置阻塞超时时间,若出现异常函数将直接报错返回
== osWaitForever //任务将一直阻塞直到锁中token被相应线程归还
== Ticks //设置具体等待时间,单位为RTOS心跳数(Ticks)

④归还互斥锁tokenosMutexRelease() ****

注意互斥锁的token归还只能由获取的线程进行,否则系统会报Resource错误。

osStatus_t osMutexRelease (osMutexId_t mutex_id);/*归还互斥锁
@retval      -osOK: 成功
             -osErrorResource: 无法归还(当前token没有被获取 或 本线程不持有互斥锁的token)
             -osErrorParameter: parameter mutex_id is NULL or invalid.
             -osErrorISR: 在中断中调用了本函数
*/
```**⑤查询当前互斥锁token的拥有者(线程)****  ***osMutexGetOwner()*********

osThreadId_t osMutexGetOwner (osMutexId_t mutex_id)/*
@retval -持有互斥锁token的线程句柄(ID);
若token未被持有或 发生错误,则返回NULL
*/


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 处理器
    +关注

    关注

    68

    文章

    19349

    浏览量

    230355
  • RTOS
    +关注

    关注

    22

    文章

    817

    浏览量

    119737
  • ISR
    ISR
    +关注

    关注

    0

    文章

    38

    浏览量

    14452
收藏 人收藏

    评论

    相关推荐

    Linux高级编程---互斥

    在Linux系统里,有很多的应用,包括互斥,文件,读写等等,信号量其实也应该是的一种。
    发表于 01-13 10:07

    信号量、互斥、自旋

    信号量、互斥、自旋http://bbs.edu118.com/forum.php?mod=viewthread&tid=488&fromuid=231(出处: 信盈达IT技术社
    发表于 08-29 09:48

    BearPi-HM_Nano开发板鸿蒙OS内核编程开发——互斥

    :不能在中断服务调用该函数参数:[td]名字描述attr互斥对象的属性.osMutexAcquire()osStatus_t osMutexAcquire(osMutexId_t mutex_id
    发表于 04-09 10:02

    如何在RK2206上使用鸿蒙LiteOS-M内核接口进行互斥编程开发

    注意的是,互斥不能在中断服务程序中使用。API分析LOS_MuxCreate()UINT32 LOS_MuxCreate(UINT32 *
    发表于 08-05 16:28

    很多变量多线程读写是使用关中断好还是使用互斥进行保护呢?

    会打断当前线程去获取同一个互斥量,由于被占,高优先级挂起,低优先级继续执行,释放互斥后高优先级执行。这样会有多两次线程切换开销。 2.如果在读写的时候进入
    发表于 05-05 14:14

    华为物联网操作系统LiteOS内核教程05-互斥

    1. LiteOS的互斥 1.1. 互斥 在多任务环境下,往往存在多个任务竞争同一共享资源的应用场景,互斥
    发表于 03-13 16:19 1210次阅读
    华为物联网操作系统LiteOS内核教程05-<b class='flag-5'>互斥</b><b class='flag-5'>锁</b>

    深入了解互斥、条件变量、读写以及自旋

    C++11只包含其中的部分。接下来我主要通过pthread的API来展开本文。 mutex(互斥量) mutex(mutual exclusive)即互斥量(互斥体)。也便是常说的互斥
    的头像 发表于 11-01 10:02 1906次阅读

    Linux中的伤害/等待互斥介绍

    序言:近期读Linux 5.15的发布说明,该版本合并了实时机制,当开启配置宏CONFIG_PREEMPT_RT的时候,这些被基于实时互斥的变体替代:mutex、ww_mutex
    的头像 发表于 11-06 17:27 2689次阅读

    Linux下线程间通讯--互斥

    互斥是一种简单的加锁的方法来控制对共享资源的存取,当多个线程访问公共资源时,为了保证同一时刻只有一个线程独占资源,就可以通过互斥加以限制,在一个时刻只能有一个线程掌握某个
    的头像 发表于 08-24 15:53 1985次阅读
    Linux下线程间通讯--<b class='flag-5'>互斥</b><b class='flag-5'>锁</b>

    Linux互斥的作用 互斥是什么

    。如果释放互斥时有一个以上的线程阻塞,那么这些阻塞的线程会被唤醒,它们都会尝试对互斥进行加锁,当有一个线程成功对互斥锁上锁之后,其它线程
    的头像 发表于 07-21 11:13 961次阅读

    自旋互斥的区别有哪些

    自旋 自旋互斥很相似,在访问共享资源之前对自旋进行上锁,在访问完成后释放自旋(解锁)
    的头像 发表于 07-21 11:19 9522次阅读

    互斥、条件变量、读写、自旋及信号量介绍

    一、互斥(同步) 在多任务操作系统中,同时运行的多个任务可能都需要使用同一种资源。这个过程有点类似于,公司部门里,我在使用着打印机打印东西的同时(还没有打印完),别人刚好也在此刻使用打印机打印东西
    的头像 发表于 11-10 16:16 2484次阅读
    <b class='flag-5'>互斥</b><b class='flag-5'>锁</b>、条件变量、读写<b class='flag-5'>锁</b>、自旋<b class='flag-5'>锁</b>及信号量介绍

    互斥和自旋的区别 自旋临界区可以被中断吗?

    互斥和自旋的区别 自旋临界区可以被中断吗? 互斥
    的头像 发表于 11-22 17:41 865次阅读

    自旋互斥的使用场景是什么

    自旋互斥是两种常见的同步机制,它们在多线程编程中被广泛使用。在本文中,我们将介绍自旋互斥
    的头像 发表于 07-10 10:05 1052次阅读

    互斥和自旋的实现原理

    互斥和自旋是操作系统中常用的同步机制,用于控制对共享资源的访问,以避免多个线程或进程同时访问同一资源,从而引发数据不一致或竞争条件等问题。 互斥
    的头像 发表于 07-10 10:07 532次阅读