【RT-Thread】互斥量

rtthread 互斥量 学习笔记

概述

怎么独享厕所?自己开门上锁,完事了自己开锁。
你当然可以进去后,让别人帮你把门:但是,命运就掌握在别人手上了。
使用队列、信号量,都可以实现互斥访问,以信号量为例:
  • 信号量初始值为 1
  • 任务 A 想上厕所,"take"信号量成功,它进入厕所
  • 任务 B 也想上厕所,"take"信号量不成功,等待
  • 任务 A 用完厕所,"give"信号量;轮到任务 B 使用
这需要有 2 个前提:
  • 任务 B 很老实,不撬门(一开始不"give"信号量)
  • 没有坏人:别的任务不会"give"信号量
可以看到,使用信号量确实也可以实现互斥访问,但是不完美。
使用互斥量可以解决这个问题,互斥量的名字取得很好:
  • 量:值为 01
  • 互斥:用来实现互斥访问
它的核心在于:谁上锁,就只能由谁开锁。

使用过程

互斥量也被称为互斥锁,使用过程如下:
  • 互斥量初始值为 1
  • 线程 A 想访问临界资源,先获得并占有互斥量,然后开始访问
  • 线程 B 也想访问临界资源,也要先获得互斥量:如果互斥量被别人占有了,线程 B 就会阻塞
  • 线程 A 使用完毕,释放互斥量;线程 B 被唤醒、得到并占有互斥量,然后开始访问临界资源
  • 线程 B 使用完毕,释放互斥量
注意 :在线程 A 占有互斥量的过程中,线程 B 、线程 C 等等,都无法释放互斥量。只
能由线程 A 也就是信号量的占有者释放

互斥量函数

互斥量是一种特殊的二值信号量。
使用互斥量时,先创建、然后去获得、释放它。

 创建/初始化

互斥量的创建有两种方法:动态分配内存、静态分配内存,
  • 动态分配内存:rt_mutex_create,从对象管理器中分配一个 mutex 对象, 并初始化这个对象
  • 静态分配内存:rt_mutex_init,互斥量的内存要事先分配好
rt_mutex_create() 函数原型如下:
rt_mutex_t rt_mutex_create (const char* name, rt_uint8_t flag);
参数
说明
name
互斥量名称
flag
互斥量标志,已废除,均按 RT_IPC_FLAG_PRIO 处理
返回值
互斥量句柄:成功,返回句柄,以后使用句柄来操作互斥量
RT_NULL :失败
rt_mutex_init() 函数原型如下:
rt_err_t rt_mutex_init (rt_mutex_t mutex, const char* name, rt_uint8_t flag);
参数
说明
mutex
互斥量对象的句柄
name
互斥量的名字
flag
互斥量标志,已废除,均按 RT_IPC_FLAG_PRIO 处理
返回值
RT_EOK :成功

删除/脱离

不再使用一个互斥量时:
  • 删除它:rt_mutex_delete(),只能删除使用 rt_mutex_create()创建的互斥量
  • 脱离它:rt_mutex_detach(),只能脱离使用 rt_mutex_init()初始化的互斥量
删除互斥量的函数为 rt_mutex_delete() ,它会释放内存。原型如下:
rt_err_t rt_mutex_delete (rt_mutex_t mutex);
删除互斥量时,如果有线程在等待该互斥量,则内核会先唤醒这些线程(线程返回值是 - RT_ERROR ),然后再释放互斥量使用的内存,最后删除互斥量对象。
脱离互斥量,就是将互斥量对象被从内核对象管理器中脱离。原型如下:
rt_err_t rt_mutex_detach (rt_mutex_t mutex);
脱离互斥量时,如果有线程在等待该互斥量,则内核会先唤醒这些线程(线程返回值是 - RT_ERROR )。

获取/释放

互斥量某一时刻只能被一个线程持有。
RT-Thread 有两个获取互斥量的函数 , 一个释放互斥量函数:
  • rt_mutex_take() 获取互斥量
  • rt_mutex_trytake() 无等待、尝试获取互斥量
  • rt_mutex_release() 释放互斥量
如果互斥量没有被其他线程持有,使用 rt_sem_take() 即可获取互斥量。
如果互斥量已被其他线程持有,使用 rt_sem_take() 获取互斥量则挂起等待,直到其他线程释放或等待时间超时。
如果互斥量没有被其他线程持有,使用 rt_mutex_trytake() 即可获取互斥量。
如果互斥量已被其他线程持有,使用 rt_mutex_trytake() 直接返回失败,不会等待。 当线程完成资源的互斥访问后,应尽快使用 rt_sem_release() 释放互斥量,使其他线程能及时获取互斥量。
注意 :拥有互斥量控制权的线程才能释放它,其他线程无法释放互斥量。
获取互斥量的函数原型如下:
rt_err_t rt_mutex_take (rt_mutex_t mutex, rt_int32_t time);
参数
说明
mutex
互斥量对象的句柄
time
超时时间,单位为系统时钟节拍( OS Tick
返回值
RT_EOK :获取互斥量成功
RT_ETIMEOUT :获取互斥量超时
RT_ERROR :获取互斥量错误

无等待、尝试获取互斥量的函数原型如下:
rt_err_t rt_mutex_trytake(rt_mutex_t mutex);
参数
说明
mutex
互斥量的句柄
返回值
RT_EOK :获取互斥量成功
RT_ETIMEOUT :获取互斥量超时
释放互斥量的函数原型如下:
rt_err_t rt_mutex_release(rt_mutex_t mutex);
参数
说明
mutex
互斥量的句柄
返回值
RT_EOK :获取互斥量成功

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一叶舞澎湃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值