欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

[RTT例程练习] 2.2 信号量之基本使用(动态/静态信号量)

程序员文章站 2022-04-12 18:49:59
...

信号量的解释: 来自百度百科: 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放

信号量的解释:

来自百度百科:

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。

RT-Thread 的信号量有静态和动态,这里同线程的静态和动态是一个意思。对信号量有两种操作,take 和 release。

程序中,首先初始化信号量为0,这时首先使用take,并只等待10个tick,故一定会超时,因为信号量初始值为0,take不到。然后release一次,信号量便增加1,这时再次take,并且使用的是wait forever 的方式,便一定能得到信号量。

程序:

#include 

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.