rt-thread的IPC机制之互斥锁源码分析

互斥锁是管理临界资源的一种有效手段。因为互斥锁是独占的,所以在一个时刻只允许一个线程占有互斥锁,利用这个性质来实现共享资源的互斥锁保护。任何时刻只允许一个线程获得互斥量对象,未能够获得互斥量对象的线程被挂起在该互斥量的等待线程队列上。


1 互斥锁控制块

/**
 * 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;
由上述源码可知,互斥锁控制块也是派生自IPC对象,而IPC对象又派生自内核对象.

value大于1时表示此互斥锁可用,小于或等于0都表示此互斥锁当前不可用.

original_priority保存着互斥锁拥有者的初始优先级,因此rt-thread为了处理互斥锁导致线程优先级翻转的问题,可能会提升互斥锁拥有者线程的优先级,这里保存原先优先级便于恢复.

hold表示此互斥锁被同一线程成功take的次数,一般情况下一个线程只会take一次互斥锁,但rt-thread也允许线程重复take同一线程,此时hold的值就用来做记录线程重复take互斥锁的次数,以便在realse同样多次时才去唤醒互斥锁上的挂起的线程.

而owner表示此互斥锁的拥有者线程,rt-thread只允许同一时间只有一个线程拥有这个互斥锁,此参数就是用来记录此线程的.

2 初始化及创建互斥锁

2.1 初始化互斥锁

/**
 * This function will initialize a mutex and put it under control of resource
 * management.
 *
 * @param mutex the mutex object
 * @param name the name of mutex
 * @param flag the flag of mutex
 *
 * @return the operation status, RT_EOK on successful
 */
rt_err_t rt_mutex_init(rt_mutex_t mutex, const char *name, rt_uint8_t flag)
{
    RT_ASSERT(mutex != RT_NULL);

    /* init object */
    rt_object_init(&(mutex->parent.parent), RT_Object_Class_Mutex, name);//初始化互斥锁的内核对象

    /* init ipc object */
    rt_ipc_object_init(&(mutex->parent));//初始化互斥锁的IPC对象

    mutex->value = 1;//设置互斥锁值初始化为1
    mutex->owner = RT_NULL;//初始化互斥锁当前没有拥有者
    mutex->original_priority = 0xFF;//初始化互斥锁原始优先级为255,即拥有者线程的优先级
    mutex->hold  = 0;//初化为当前互斥锁的被take的次数为0(同一线程)

    /* set flag */
    mutex->parent.parent.flag = flag;//设置互斥锁的内核对象标志

    return RT_EOK;
}

注意互斥锁在初始化时其值value被初始化为1,即默认情况下其是可用的.在其被take之后value值减1变为0时才不可用.

2.2 创建互斥锁

/**
 * This function will create a mutex from system resource
 *
 * @param name the name of mutex
 * @param flag the flag of mutex
 *
 * @return the created mutex, RT_NULL on error happen
 *
 * @see rt_mutex_init
 */
rt_mutex_t rt_mutex_create(const char *name, rt_uint8_t flag)
{
    struct rt_mutex *mutex;

    RT_DEBUG_NOT_IN_INTERRUPT;//确保此函数不是在ISR中使用

    /* allocate object */
    mutex = (rt_mutex_t)rt_object_allocate(RT_Object_Class_Mutex, name);//动态分配一个互斥锁
    if (m
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值