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


    信号量的解释:

    来自百度百科:

    信号量(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.


  • 相关阅读:
    数据的图表统计highcharts
    spring文件的上传和下载
    项目随笔@Service("testService")-------第二篇
    spring的四种数据源配置
    spring之interceptor篇
    spring过滤器篇
    SecurityManager篇
    Apache shiro篇
    日期工具方法
    定时器CronExpression配置说明详解
  • 原文地址:https://www.cnblogs.com/lyyyuna/p/4123944.html
Copyright © 2020-2023  润新知