IPC: Inter proess communication 大的任务中的各任务信息交互配合,内容包括信号量,互斥锁,消息队列,邮箱,事件
本篇文章,只讨论第一个内容,信号量
1.信号量的创建
和线程的创建方式类似,信号量的创建也分动态dynamic和静态static的分别,分别由两个函数实现。
/*静态信号量的线程控制块*/
static struct rt_semaphore static_sem;
/*指向动态信号量的指针*/
static rt_sem_t dynamic_sem;
/*静态创建*/
rt_sem_init(&static_sem,"name","number",“time”);
/*动态创建*/
dynamic_sem = rt_sem_creat("name","number",“time”);
"number"是设置信号量的初始值,如果设置为0就证明没有可以用得信号量,只有等待信号量被释放才能获取到信号量。
具体内容可以参看文末的例程。
2.信号量的获取和释放
/*信号量的获取函数*/
rt_sem_take(xx,"waitting time");
/*信号量的释放函数*/
rt_sem_release(xx);
rt_sem_take()函数会有一个返回值,我们一般不对这个返回值忽略,因为这个函数中包含rt_schedule()片段,"waiting time"参数可以设置为你需要等待的时间,当然不能超出rt_uint32_t的数据限制,超出等待时间后,获取失败的反馈,向下一段函数执行;也可以设置为RT_WARTING_FOREVER,用来一直获取信号量,除非获取到信号量才开始向下一段函数执行。
rt_sem_release()函数中,也包含rt_schedule()片段。而且是刚释放完一个信号量,便开启任务调度。所以在这两个线程中,你基本没有发现rt_thread_delay()类似的任务挂起的函数,而且两个任务都可以正常的完成,原因就在于此。
3.信号量的删除
/*删除静态函数*/
rt_sem_detach();
/*删除动态函数*/
rt_sem_delete();
有创建就会有删除,删除函数也是类似的。
4.例程
#include <rtthread.h>
#define THREAD_PRIORITY 25
#define THREAD_TIMESLICE 5
/* 指向信号量的指针 */
static rt_sem_t dynamic_sem = RT_NULL;
/* 指向信号量的线程控制块 */
static struct rt_semaphore static_sem;
ALIGN(RT_ALIGN_SIZE)
static char thread1_stack[1024];
static struct rt_thread thread1;
static void rt_thread1_entry(void *parameter)
{
static rt_uint8_t count = 0;
while(1)
{
if(count <= 100)
{
count++;
}
else
return;
/* count每计数10次,就释放一次信号量 */
if(0 == (count % 10))
{
rt_kprintf("t1 release a dynamic semaphore.\n" );
// rt_sem_release(dynamic_sem);
rt_sem_release(&static_sem);
}
}
}
ALIGN(RT_ALIGN_SIZE)
static char thread2_stack[1024];
static struct rt_thread thread2;
static void rt_thread2_entry(void *parameter)
{
static rt_err_t result;
static rt_uint8_t number = 0;
while(1)
{
/* 永久方式等待信号量,获取到信号量,则执行number自加的操作 */
// result = rt_sem_take(dynamic_sem, 100);
// result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER);//一直等待
result = rt_sem_take(&static_sem, 100);
// result = rt_sem_take(&static_sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
rt_kprintf("t2 take a dynamic semaphore, failed.\n");
// rt_sem_delete(dynamic_sem);
rt_sem_detach(&static_sem);
return;
}
else
{
number++;
rt_kprintf("t2 take a dynamic semaphore. number = %d\n" ,number);
}
}
}
/* 信号量示例的初始化 */
int semaphore_sample()
{
// /* 创建一个动态信号量,初始值是0 */
// dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_FIFO);
// if (dynamic_sem == RT_NULL)
// {
// rt_kprintf("create dynamic semaphore failed.\n");
// return -1;
// }
// else
// {
// rt_kprintf("create done. dynamic semaphore value = 0.\n");
// }
/* 初始化一个静态信号量,初始值是0 */
rt_err_t result;
result = rt_sem_init(&static_sem,"ssem",0,RT_IPC_FLAG_FIFO);
if(RT_EOK != result)
{
rt_kprintf("init static semaphore failed.\n");
return -1;
}
else
{
rt_kprintf("init done static semaphore value = 0\n");
}
rt_thread_init(&thread1,
"thread1",
rt_thread1_entry,
RT_NULL,
&thread1_stack[0],
sizeof(thread1_stack),
THREAD_PRIORITY, THREAD_TIMESLICE);
rt_thread_startup(&thread1);
rt_thread_init(&thread2,
"thread2",
rt_thread2_entry,
RT_NULL,
&thread2_stack[0],
sizeof(thread2_stack),
THREAD_PRIORITY-1, THREAD_TIMESLICE);
rt_thread_startup(&thread2);
return 0;
}
里面的代码,按照需要看是否注释某些部分。