资料介绍
引 言
互 斥 量 , 即 互 斥 信 号 量 ( Mutex, Mutual Exclusion 的 缩 写 ) 。 互
斥 量 的 主 要 作 用 是 对 资 源 实 现 互 斥 访 问 。二 值 信 号 量 也 可 以 实 现 对
资 源 的 互 斥 访 问 ,那 么 为 何 要 引 入 互 斥 量 呢 ? 互 斥 量 和 信 号 量 有 什
么 不 同 呢 ?
这 其 中 涉 及 到 两 个 重 要 的 知 识 点 :
优 先 级 翻 转
优 先 级 继 承
理 解 了 这 两 点 内 容 , 互 斥 量 也 就 基 本 掌 握 了 。 理 解 互 斥 量
互 斥 量 是 一 种 保 护 共 享 资 源 的 方 法 ,当 一 个 线 程 拥 有 互 斥 量 时 ,可
以 保 护 共 享 资 源 不 被 其 他 线 程 破 坏 。
一 个 线 程 持 有 互 斥 量 时 ,其 他 线 程 不 能 再 持 有 它 ,持 有 该 互 斥 量 的
线 程 也 能 够 再 次 获 得 这 个 互 斥 量 ,而 不 被 挂 起 ,即 互 斥 量 可 以 递 归
持 有 。 对 于 信 号 量 , 不 支 持 递 归 获 取 , 若 递 归 获 取 会 形 成 死 锁 。
互 斥 量 可 以 防 止 线 程 优 先 级 翻 转 ,二 值 信 号 量 不 支 持 。那 么 什 么 是
优 先 级 翻 转 呢 ?
优 先 级 翻 转 问 题
优 先 级 翻 转 通 俗 解 释 :当 一 个 高 优 先 级 线 程 试 图 通 过 信 号 量 机 制 访
问 共 享 资 源 时 ,如 果 该 信 号 量 已 被 一 个 低 优 先 级 线 程 持 有 ,而 这 个
低 优 先 级 线 程 在 运 行 过 程 中 可 能 又 被 其 它 一 些 中 等 优 先 级 的 线 程
抢 占 , 因 此 造 成 高 优 先 级 线 程 被 许 多 具 有 较 低 优 先 级 的 线 程 阻 塞 。
举 例 说 明 如 下 图 :
三 个 线 程 ,优 先 级 由 高 到 低 分 别 为 :Thread1 > Thread2 > Thread3。
线 程 Thread1 运 行 过 程 中 需 要 访 问 某 个 共 享 资 源 , 发 现
Thread3 正 在 访 问 , Thread1 进 入 挂 起 状 态 , 等 待 Thread3 释
放 共 享 资 源 。
在 Thread3 执 行 过 程 中 ,Thread2 就 绪 ,抢 占 了 Thread3 的 运
行 。等 Thread2 执 行 完 毕 后 ,Thread1 接 着 执 行 ,释 放 共 享 资 源
后 , Thread1 得 以 继 续 运 行 。
在 这 种 情 况 下 , 出 现 了 优 先 级 翻 转 的 问 题 : 线 程 Thread2 优 先
Thread1 执 行 完 毕 ,即 Thread1 需 要 等 待 Thread2 执 行 完 毕 后
才 有 机 会 运 行 , 这 与 基 于 优 先 级 的 抢 占 式 调 度 正 好 反 了 。
因 此 ,RTOS 引 入 了 互 斥 量 ,用 于 避 免 二 值 信 号 量 使 用 过 程 产 生 的
优 先 级 翻 转 问 题 。
互 斥 量 之 所 以 能 够 防 止 优 先 级 翻 转 问 题 的 发 生 ,是 因 为 在 实 现 过 程
中 采 用 了 优 先 级 继 承 算 法 。
优 先 级 继 承
因 此 ,继 承 优 先 级 的 线 程 避 免 了 系 统 资 源 被 任 何 中 间 优 先 级 的 线 程
抢 占 。
在 上 例 中 , 最 低 优 先 级 线 程 Thread3 在 拥 有 互 斥 量 过 程 中 , 会 临
时 将 优 先 级 提 高 到 与 Thread1 的 优 先 级 相 同 ,即 使 线 程 Thread2
达 到 就 绪 状 态 ,也 不 能 够 立 即 执 行 ,需 要 等 待 Thread1 执 行 完 毕 ,
才 具 备 运 行 条 件 。
注 意 ,在 获 得 互 斥 量 后 ,应 该 尽 快 释 放 ,并 在 持 有 互 斥 量 的 过 程 中 ,
不 得 再 更 改 持 有 互 斥 量 线 程 的 优 先 级 。
互 斥 量 控 制 块
RT-Thread 管 理 互 斥 量 的 数 据 结 构 为 互 斥 量 控 制 块 , 由 结 构
体 struc t rt_mutex 表 示 , 其 具 体 定 义 如 下 :
另 外 rt_mutex_t 表 示 的 是 互 斥 量 的 句 柄 , 也 就 是 指 向 互 斥 量 控 制 块
的 指 针 。
从 面 向 对 象 的 角 度 来 看 , rt_mutex 对 象 是 从 rt_ipc_object 派 生 而 来 ,
由 IPC 容 器 管 理 。 互 斥 量 的 操 作
在 RT-Thread 中 , 对 一 个 互 斥 量 的 操 作 包 括 :
创 建 /初 始 化 互 斥 量
获 取 互 斥 量
释 放 互 斥 量
删 除 /脱 离 互 斥 量
其 中 常 用 的 操 作 无 非 就 是 :创 建 互 斥 量 、获 取 互 斥 量 、释 放 互 斥 量 。
注 意 : 互 斥 量 不 能 在 中 断 服 务 程 序 中 使 用 。
1. 创 建 互 斥 量
RT-Thread 中 动 态 创 建 互 斥 量 的 函 数 接 口 如 下 :
调 用 此 函 数 创 建 一 个 互 斥 量 时 ,内 核 会 自 动 创 建 一 个 互 斥 量 控 制 块 ,
并 从 内 核 对 象 管 理 器 中 分 配 一 个 mutex 对 象 , 然 后 对 其 初 始 化 。
参 数 name 为 互 斥 量 的 名 字 ; flag 用 来 设 置 等 待 互 斥 量 的 线 程 队 列
排 序 方 式 。
互 斥 量 创 建 成 功 ,函 数 返 回 互 斥 量 句 柄 ;创 建 失 败 ,则 返 回 RT_NULL。
参 数 Flag 的 取 值 有 两 种 :
RT_IPC_FLAG_PRIO,多 个 等 待 互 斥 量 的 线 程 按 照 优 先 级 高 低 进 行 排
序 。
RT_IPC_FLAG_FIFO,多 个 等 待 互 斥 量 的 线 程 按 照 先 进 先 出 的 方 式 进
行 排 序 。
静 态 方 式 创 建 互 斥 量 需 要 两 步 : ( 1) 定 义 一 个 互 斥 量 控 制 块 结 构
体 变 量 ( 2) 调 用 函 数 对 其 初 始 化 。
初 始 化 互 斥 量 的 函 数 接 口 如 下 :
rt_err_t rt_mutex_init (rt_mutex_t mutex, const char* name, rt_uint8_t
flag)
该 函 数 对 参 数 mutex 指 定 的 互 斥 量 控 制 块 进 行 初 始 化 。另 外 两 个 参
数 name 和 flag 与 动 态 创 建 函 数 相 同 。
2. 获 取 互 斥 量
RT-thread 提 供 的 获 取 互 斥 量 的 函 数 接 口 如 下 ,线 程 通 过 调 用 此 函
数 来 获 取 某 个 互 斥 量 。
rt_err_t rt_mutex_take (rt_mutex_t mutex, rt_int32_t time)
参 数 mutex 为 互 斥 量 句 柄 ; time 表 示 等 待 超 时 时 间 , 单 位 为 系 统 节
拍 。
如 果 互 斥 量 可 用 ,那 么 申 请 互 斥 量 的 线 程 将 会 成 功 获 取 ,线 程 就 有
了 对 互 斥 量 的 所 有 权 。若 该 线 程 继 续 获 取 互 斥 量 ,则 互 斥 量 的 持 有
计 数 加 1, 当 先 线 程 不 会 挂 起 等 待 ( 即 支 持 递 归 获 取 互 斥 量 ) 。
如 果 互 斥 量 已 经 被 其 他 线 程 占 用 ,则 当 前 线 程 会 进 入 挂 起 状 态 ,等
待 其 他 线 程 释 放 该 互 斥 量 或 者 等 待 超 时 时 间 达 到 。
rt_mutex_take() 返 回 RT_EOK 表 示 获 取 成 功 ;返 回 -RT_ETIMEOUT 表
示 获 取 超 时 ; -RT_ERROR 获 取 失 败 。
3. 释 放 互 斥 量
当 线 程 用 完 互 斥 资 源 后 ,应 该 尽 快 释 放 它 占 据 的 互 斥 量 ,使 得 其 他
线 程 能 够 及 时 获 取 。
部分文件列表
文件名 |
大小 |
RT-Thread快速入门-互斥量.pdf |
283K |
全部评论(0)