一、互斥量控制块:在include/rtdef.h中

#ifdef RT_USING_MUTEX
/**
* Mutual exclusion (mutex) structure
*/
struct rt_mutex
{
struct rt_ipc_object parent; /**< inherit from ipc_object */ //派生自IPC对象 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 */ //此互斥锁当前已被几个线程(同一线程)take的次数 struct rt_thread *owner; /**< current owner of mutex */ //此互斥锁的拥有者线程
};
typedef struct rt_mutex *rt_mutex_t;
#endif
互斥锁控制块也是派生自IPC对象,而IPC对象又派生自内核对象.
value: 大于0时表示此互斥锁可用,小于或等于0都表示此互斥锁当前不可用.
original_priority:保存着互斥锁拥有者的初始优先级,因此rt-thread为了处理互斥锁导致线程优先级翻转的问题,可能会提升互斥锁拥有者线程的优先级,这里保存原先优先级便于恢复。
hold: 表示此互斥锁被同一线程成功take的次数,一般情况下一个线程只会take一次互斥锁,但rt-thread也允许线程重复take同一线程,此时hold的值就用来做记录线程重复take互斥锁的次数,以便在realse同样多次时才去唤醒互斥锁上的挂起的线程。
owner: 表示此互斥锁的拥有者线程,rt-thread只允许同一时间只有一个线程拥有这个互斥锁,此参数就是用来记录此线程的。

二、互斥量相关接口:在src/ipc.c中

创建互斥量:
rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag);
可以调用rt_mutex_create函数创建一个互斥量,它的名字有name所指定。创建的互斥量由于指定的flag不同,而有不同的意义: 使用PRIO优先级flag创建的IPC对象,在多个线程等待资源时,将由优先级高的线程优先获得资源。而使用FIFO先进先出flag创建的IPC对象,在多个线程等待资源时,将按照先来先得的顺序获得资源。 删除互斥量:
rt_err_t rt_mutex_delete(rt_mutex_t mutex);
当删除一个互斥量时,所有等待此互斥量的线程都将被唤醒,等待线程获得的返回值是-RT_ERROR。然后系统将该互斥量从内核对象管理器链表中删除并释放互斥量占用的内存空间。
初始化互斥量:
rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag);
使用该函数接口时,需指定互斥量对象的句柄(即指向互斥量控制块的指针),互斥量名称以及互斥量标志。互斥量标志可用上面创建互斥量函数里提到的标志。 脱离互斥量:
rt_err_t rt_mutex_detach(rt_mutex_t mutex);
使用该函数接口后,内核先唤醒所有挂在该互斥量上的线程(线程的返回值是-RT_ERROR),然后系统将该互斥量从内核对象管理器链表中删除。
获取互斥量:
rt_err_t rt_mutex_take(rt_mutex_t mutex, rt_int32_t time);
线程通过互斥量申请服务获取互斥量的所有权。线程对互斥量的所有权是独占的,某一个时刻一个互斥量只能被一个线程持有。
如果互斥量没有被其他线程控制,那么申请该互斥量的线程将成功获得该互斥量。如果互斥量已经被当前线程线程控制,则该互斥量的持有计数加1,当前线程也不会挂起等待。如果互斥量已经被其他线程占有,则当前线程在该互斥量上挂起等待,直到其他线程释放它或者等待时间超过指定的超时时间。
当前线程获取互斥量的时间已到还是未成功时,当前线程的thread->error将在定时器的超时回调函数中设置为-RT_ETIMEOUT,而如果另一线程在释放互斥锁rt_mutex_release函数中如果唤醒当前阻塞的线程,在这个过程中thread->error的值将一直保持原样RT_EOK。这就是为什么可以通过判断thread->error的值来得知当前线程是否已经获得互斥量。 释放互斥量:
rt_err_t rt_mutex_release(rt_mutex_t mutex);
使用该函数接口时,只有已经拥有互斥量控制权的线程才能释放它,每释放一次该互斥量,它的持有计数就减1。当该互斥量的持有计数为零时(即持有线程已经释放所有的持有操作),它变为可用,等待在该信号量上的线程将被唤醒。如果线程的运行优先级被互斥量提升,那么当互斥量被释放后,线程恢复为持有互斥量前的优先级。
只有在确保互斥量再没有线程take时,即hold=0时,才去唤醒挂起在此互斥量上的第一个线程,并将此互斥量的拥有者线程设置为此被唤醒的线程,并记录唤醒线程的优先级,因为唤醒线程即将成功拥有互斥量,所以互斥量的hold值再次加1。
控制互斥量:
rt_err_t rt_mutex_control(rt_mutex_t mutex, rt_uint8_t cmd, void *arg);
该函数为空函数。函数只返回-RT_ERROR。

RT-thread内核之互斥量的更多相关文章

  1. php Pthread 多线程 (三) Mutex 互斥量

    当我们用多线程操作同一个资源时,在同一时间内只能有一个线程能够对资源进行操作,这时就需要用到互斥量了.比如我们对同一个文件进行读写操作时. <?php class Add extends Thr ...

  2. posix thread互斥量

    互斥量 互斥量(Mutex)是“mutual exclusion”的缩写.互斥量是实现线程同步,和保护同时写共享数据的主要方法.使用互斥量的典型顺序如下:1. 创建和初始一个互斥量 2. 多个线程尝试 ...

  3. Linux内核中锁机制之完成量、互斥量

    在上一篇博文中笔者分析了关于信号量.读写信号量的使用及源码实现,接下来本篇博文将讨论有关完成量和互斥量的使用和一些经典问题. 八.完成量 下面讨论完成量的内容,首先需明确完成量表示为一个执行单元需要等 ...

  4. 大话Linux内核中锁机制之完成量、互斥量

    大话Linux内核中锁机制之完成量.互斥量 在上一篇博文中笔者分析了关于信号量.读写信号量的使用及源码实现,接下来本篇博文将讨论有关完成量和互斥量的使用和一些经典问题. 八.完成量 下面讨论完成量的内 ...

  5. 【Linux】Mutex互斥量线程同步的例子

    0.互斥量  Windows下的互斥量 是个内核对象,每次WaitForSingleObject和ReleaseMutex时都会检查当前线程ID和占有互斥量的线程ID是否一致. 当多次Wait**时就 ...

  6. CPP-基础:互斥量

    互斥量的用途和临界区很像.它与临界区的差别在于可以跨线程使用,可以用来同步进行多个线程间的数据访问,但是是以牺牲速度为代价的.只有临界区是非核心对象,那么互斥量就是一个核心对象了.核心对象的特点是有所 ...

  7. 1.linux系统基础笔记(互斥量、信号量)

    操作系统是很多人每天必须打交道的东西,因为在你打开电脑的一刹那,随着bios自检结束,你的windows系统已经开始运行了.如果问大家操作系统是什么?可能有的人会说操作系统就是windows,就是那些 ...

  8. Linux 自旋锁,互斥量(互斥锁),读写锁

    自旋锁(Spin Lock) 自旋锁类似于互斥量,不过自旋锁不是通过休眠阻塞进程,而是在取得锁之前一直处于忙等待的阻塞状态.这个忙等的阻塞状态,也叫做自旋. 自旋锁通常作为底层原语实现其他类型的锁. ...

  9. 多线程相关------互斥量Mutex

    互斥量(Mutex) 互斥量是一个可以处于两态之一的变量:解锁和加锁.只有拥有互斥对象的线程才具有访问资源的权限.并且互斥量可以用于不同进程中的线程的互斥访问. 相关函数: CreateMutex用于 ...

随机推荐

  1. Making AJAX Applications Crawlable

    https://developers.google.com/webmasters/ajax-crawling/

  2. nio之netty3的应用

    1.netty3是nio的封装版本.在使用上面比nio的直接使用更好.nio简单使用都是单线程的方式(比如:一个服务员服务很多客户),但是netty3的方式不一样的是,引入线程池的方式来实现服务的通信 ...

  3. CakePHP 总结

    1. 处理任何保存或获取数据的操作最好都写在模型(Model)中.这个概念通常被称为fat model. 2. 返回上一条插入记录的ID, $this->Example->getInser ...

  4. MVC、MVVM

    一.MVC 所谓的 MVC 是指: Model: 数据的拥有者,实现具体的业务逻辑. View: 具体的用户界面,如按钮.列表.图片. Controller: 负责将 View 中用户的动作传达给 M ...

  5. 第三十九篇 Python异常处理

    一. 什么是异常 异常就是程序运行时发生的错误,在程序出现错误时,则会产生一个异常,若程序没有处理它,则会抛出该异常,程序的运行也随之终止,在python中,错误触发的异常如下 错误分成两种: #语法 ...

  6. 第4章 TCP/IP通信案例:访问Internet上的Web服务器

    第4章 TCP/IP通信案例:访问Internet上的Web服务器 4.2 部署代理服务器 书中为了演示访问Internet上的Web服务器的全过程,使用了squid代理服务器程序模拟了一个代理服务器 ...

  7. Fluent Python: @property

    Fluent Python 9.6节讲到hashable Class, 为了使Vector2d类可散列,有以下条件: (1)实现__hash__方法 (2)实现__eq__方法 (3)让Vector2 ...

  8. wpa_supplicant之eloop_run分析

    部分内容转自http://blog.chinaunix.net/uid-20273473-id-3128151.html 重要结构体!!! struct eloop_sock { int sock; ...

  9. 福大软工1816:Alpha(7/10)

    Alpha 冲刺 (7/10) 队名:Jarvis For Chat 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务: 文字/口头描述: 1.完成 ...

  10. JAVA mysql数据库 配置

    mysql 版本 5.7 数据库连接版本 <!--MySql--><dependency> <groupId>mysql</groupId> <a ...