rt-thread的IPC机制之信号量源码分析

rt-thread操作系统的IPC(Inter-Process Communication,进程间通信)包含有信号量,互斥锁,事件,邮箱,消息队列.

本文主要针对信号量.信号量是用来解决线程同步和互斥的通用工具,和互斥量类似,信号量也可用作资源互斥访问,但信号量没有所有者的概念,在应用上比互斥量更广泛。信号量比较简单,不能解决优先级翻转问题,但信号量是一种轻量级的对象,比互斥量小巧、灵活。因此在很多对互斥要求不严格的系统中(或者不会造成优先级翻转的情况下),经常使用信号量来管理互斥资源。

1 信号量控制块

/**
 * Semaphore structure
 */
struct rt_semaphore
{
    struct rt_ipc_object parent;                        /**< inherit from ipc_object *///派生自IPC对象

    rt_uint16_t          value;                         /**< value of semaphore. *///信号量计数器
};
typedef struct rt_semaphore *rt_sem_t;

value为信号计数器,此信号量多次被释放时将会累加,在被获取时则将减1,当其值为0时,再请求获取的线程将会被挂起到挂起链表中。

parent为一rt_ipc_object即IPC对象,其定义如下:

/**
 * Base structure of IPC object
 */
struct rt_ipc_object
{
    struct rt_object parent;                            /**< inherit from rt_object *///可知其派生自内核对象

    rt_list_t        suspend_thread;                    /**< threads pended on this resource *///线程挂起链表
};

从rt_ipc_object的定义结构可知其派生自rt_object结构,即内核对象的定义(参考http://blog.csdn.net/flydream0/article/details/8568463),而其它IPC,如互斥锁,事件,邮箱,消息队列都是从rt_ipc_object派生。

另外,IPC对象还包含一挂起链表,用来保存因此IPC对象而挂起的线程.

2 信号量的创建与初始化

2.1 初始化

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

    /* init object */
    rt_object_init(&(sem->parent.parent), RT_Object_Class_Semaphore, name);//初始化信号量的内核对象

    /* init ipc object */
    rt_ipc_object_init(&(sem->parent));//初始化信号量的IPC对象

    /* set init value */
    sem->value = value;//设置信号量计数器的值

    /* set parent */
    sem->parent.parent.flag = flag;//设置信号量的内核对象的标志

    return RT_EOK;
}

其中rt_object_init已在之前介绍rt-thread的内核对象中相关文章中已有介绍(参见: http://blog.csdn.net/flydream0/article/details/8568463),rt_ipc_object_init函数见如下:

/**
 * @addtogroup IPC
 */

/*@{*/

/**
 * This function will initialize an IPC object
 *
 * @param ipc the IPC object
 *
 * @return the operation status, RT_EOK on successful
 */
rt_inline rt_err_t rt_ipc_object_init(struct rt_ipc_object *ipc)
{
    /* init ipc object */
    rt_list_init(&(ipc->suspend_thread));//初始化线程挂起链表

    return RT_EOK;
}
初始化及创建信号量很简单,一个是静态初始化,一个是动态分配的然后再初始化,不做过多解释.

2.2 创建信号量

/**
 * This function will create a semaphore from system resource
 *
 * @param name the name of semaphore
 * @param value the init value of semaphore
 * 
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值