信号量的解释:
来自百度百科:
信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。
RT-Thread 的信号量有静态和动态,这里同线程的静态和动态是一个意思。对信号量有两种操作,take 和 release。
程序中,首先初始化信号量为0,这时首先使用take,并只等待10个tick,故一定会超时,因为信号量初始值为0,take不到。然后release一次,信号量便增加1,这时再次take,并且使用的是wait forever 的方式,便一定能得到信号量。
程序:
#include <rtthread.h>
static struct rt_semaphore static_sem;
static rt_sem_t dynamic_sem = RT_NULL;
static rt_uint8_t thread1_stack[1024];
struct rt_thread thread1;
static void rt_thread_entry1(void *parameter)
{
rt_err_t result;
rt_tick_t tick;
/* static semaphore demo */
tick = rt_tick_get();
/* try to take the sem, wait 10 ticks */
result = rt_sem_take(&static_sem, 10);
if (result == -RT_ETIMEOUT)
{
if (rt_tick_get() - tick != 10)
{
rt_sem_detach(&static_sem);
return ;
}
rt_kprintf("take semaphore timeout\n");
}
else
{
rt_kprintf("take a static semaphore, failed.\n");
rt_sem_detach(&static_sem);
return ;
}
/* release the semaphore */
rt_sem_release(&static_sem);
/* wait the semaphore forever */
result = rt_sem_take(&static_sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
rt_kprintf("take a static semaphore, failed.\n");
rt_sem_detach(&static_sem);
return ;
}
rt_kprintf("take a static semaphore, done.\n");
/* detach the semaphore object */
rt_sem_detach(&static_sem);
//}
/* dynamic thread pointer */
//static void thread2_entry(void *parameter)
//{
// rt_err_t result;
// rt_tick_t tick;
tick = rt_tick_get();
/* try to take the semaphore, wait for 10 ticks */
result = rt_sem_take(dynamic_sem, 10);
if (result == -RT_ETIMEOUT)
{
if (rt_tick_get() - tick != 10)
{
rt_sem_delete(dynamic_sem);
return ;
}
rt_kprintf("take semaphore timeout\n");
}
else
{
rt_kprintf("take a dynamic semaphore, failed.\n");
rt_sem_delete(dynamic_sem);
return ;
}
/* release the dynamic semaphore */
rt_sem_release(dynamic_sem);
/* wait forever */
result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER);
if (result != RT_EOK)
{
rt_kprintf("take a dynamic semaphore, failed.\n");
rt_sem_delete(dynamic_sem);
return ;
}
rt_kprintf("take a dynamic semaphore, done.\n");
/* delete the semaphore*/
rt_sem_delete(dynamic_sem);
}
//static rt_thread_t tid = RT_NULL;
int rt_application_init()
{
rt_err_t result;
result = rt_sem_init(&static_sem,
"ssem",
0, RT_IPC_FLAG_FIFO);
if (result != RT_EOK)
{
rt_kprintf("init static semaphore failed. \n");
return -1;
}
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;
}
/* thread1 init */
rt_thread_init(&thread1,
"t1",
rt_thread_entry1, RT_NULL,
&thread1_stack[0], sizeof(thread1_stack),
11, 5
);
rt_thread_startup(&thread1);
return 0;
}
结果为:
take semaphore timeout
take a staic semaphore, done.
take semaphore timeout
take a dynamic semaphore, done.