rt-thread操作系统的IPC(Inter-Process Communication,进程间通信)包含有信号量,互斥锁,事件,邮箱,消息队列.
本文主要针对信号量.
1 信号量控制块
[cpp]
/**
* 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为信号计数器,parent为一rt_ipc_object即IPC对象,其定义如下:
[cpp]
/**
* 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),另外,它不包含一链表,用来保存因此信号量而挂起的线程.
2 信号量的创建与初始化
2.1 初始化
[cpp]
/**
* 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函数见如下:
[cpp]
/**
* @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 创建信号量
[cpp]
/**
* This function will create a semaphore from system resource
*
* @param name the name of semaphore
* @param value the init value of semaphore
* @param flag the flag of semaphore
*
* @return the created semaphore, RT_NULL on error happen
*
* @see rt_sem_init
*/
rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag)
{
rt_sem_t sem;
RT_DEBUG_NOT_IN_INTERRUPT;//确保此函数不是在中断中使用
/* allocate object */
sem = (rt_sem_t)rt_object_allocate(RT_Object_Class_Semaphore, name);//动态分配内核对象
if (sem == RT_NULL)
return sem;
/* init ipc object */
rt_ipc_object_init(&(sem->parent));//初始化信号量的IPC对象
/* set init value */
sem->value = value;//初始化信号量的计数器值
/* set parent */
sem->parent.parent.flag = flag;//设置信号量的内核对象的标志
return sem;
}
3 脱离及删除信号量
3.1 脱离信号量
[cpp]
/**
* This function will detach a semaphore from resource management
*
* @param sem the semaphore object
*
* @return the operation status, RT_EOK on successful
*
* @see rt_sem_delete
*/
rt_err_t rt_sem_detach(rt_sem_t sem)
{
RT_ASSERT(sem != RT_NULL);
/* wakeup all suspend threads */
rt_ipc_list_resume_all(&(sem->parent.suspend_thread));//唤醒所有信号量内挂起的线程
/* detach semaphore object */
rt_object_detach(&(sem->parent.parent));//脱离信号量的内核对象
return RT_EOK;
}
其中rt_ipc_list_resume_all函数如下:
[cpp]
/**
* This function will resume all suspended threads in a list, including
* suspend list of IPC object and private list of mailbox etc.
*
* @param list of the threads to resume
*