zoukankan      html  css  js  c++  java
  • RT-Thread信号量的基本操作

    抽象的来讲,信号量的特性如下:信号量是一个非负整数(车位数),所有通过它的线程/进程(车辆)都会将该整数减一(通过它当然是为了使用资源),当该整数值为 0 时,所有试图通过它的线程都将处于等待状态。在信号量上我们定义两种操作: take ( 获取) 和Release(释放)。当一个线程调用 take 操作时,它要么得到资源然后将信号量减一,要么
    一直等下去(指放入阻塞队列),直到信号量大于等于一时。 Release(释放)实际上是在信号量上执行加操作, take(获取)实际上是在信号量上执行减操作。RT-Thread 中的信号量有静态和动态之分(同静态线程、动态线程), 和信号量有关的操作如下:
      初始化—rt_sem_init()( 对应静态信号量) ;
      建立—rt_sem_create()( 对应动态信号量);
      获取—rt_sem_take();
      释放—rt_sem_release();
      脱离—rt_sem_detach()( 对应静态信号量) ;
      删除—rt_sem_delete()( 对应动态信号量) ;

    /**********************************************************************************************************
    *
    *    模块名称 : 功能演示
    *    文件名称 : test.c
    *    版    本 : V1.0
    *    说    明 :
    *    修改记录 :
    *        版本号  日期        作者                        说明
    *
    *        v1.0    2013-4-20   jiezhi320(UP MCU 工作室)    演示信号量的基本操作 源码来自官方教程文件
    *
    *    Copyright (C), 2012-2013,
    *   淘宝店:   http://shop73275611.taobao.com
    *   QQ交流群: 258043068
    *
    **********************************************************************************************************/
    #include <rtthread.h>
    #include <stm32f10x.h>
    #include "test.h"
    
    rt_uint32_t  g_tmp;/* 定义一个全局变量*/
    
    /*  变量分配4字节对齐 */
    ALIGN(RT_ALIGN_SIZE)
    
    /*  静态线程的 线程堆栈*/
    static rt_uint8_t thread1_stack[512];
    
    /* 静态线程的 线程控制块 */
    static struct rt_thread thread_test1;
    
    static void test1_thread_entry(void* parameter);
    
    
    /* 信号量控制块 */
    static struct rt_semaphore static_sem;
    /* 指向信号量的指针 */
    static rt_sem_t dynamic_sem = RT_NULL;
    
    rt_err_t demo_thread_creat(void)
    {
        rt_err_t result;
    
        /* 初始化静态信号量,初始值是0 */
        result = rt_sem_init(&static_sem, "ssem", 0, RT_IPC_FLAG_FIFO);
        if (result != RT_EOK)
        {
            rt_kprintf("init static semaphore failed.
    ");
            return -1;
        }
    
        /* 创建一个动态信号量,初始值是0 */
        dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_FIFO);
        if (dynamic_sem == RT_NULL)
        {
            rt_kprintf("create dynamic semaphore failed.
    ");
            return -1;
        }
    
        /* 创建静态线程 : 优先级 16 ,时间片 5个系统滴答 */
        result = rt_thread_init(&thread_test1,
                                "test1",
                                test1_thread_entry, RT_NULL,
                                (rt_uint8_t*)&thread1_stack[0], sizeof(thread1_stack), 16, 5);
    
        if (result == RT_EOK)
        {
            rt_thread_startup(&thread_test1);
        }
        return 0;
    }
    
    void test1_thread_entry(void* parameter)
    {
        rt_err_t result;
        rt_tick_t tick;
    
        /* 1. staic semaphore demo */
        /* 获得当前的OS Tick */
        tick = rt_tick_get();
    
        /* 试图持有信号量,最大等待10个OS Tick后返回 */
        result = rt_sem_take(&static_sem, 10);  //获取
        if (result == -RT_ETIMEOUT)
        {
            /* 超时后判断是否刚好是10个OS Tick */
            if (rt_tick_get() - tick != 10)
            {
                rt_sem_detach(&static_sem);     //脱离—rt_sem_detach()( 对应静态信号量) ;
                return ;
            }
            rt_kprintf("take semaphore timeout
    ");  //////////////////////////////////////
        }
        else
        {
            /* 因为没有其他地方释放信号量,所以不应该成功持有信号量,否则测试失败 */
            rt_kprintf("take a static semaphore, failed.
    ");
            rt_sem_detach(&static_sem);     //脱离—rt_sem_detach()( 对应静态信号量) ;     
            return ;
        }
    
        /* 释放一次信号量 */
        rt_sem_release(&static_sem);    //释放—rt_sem_release();
    
        /* 永久等待方式持有信号量 */
        result = rt_sem_take(&static_sem, RT_WAITING_FOREVER);//获取—rt_sem_take();
        if (result != RT_EOK)
        {
            /* 不成功则测试失败 */
            rt_kprintf("take a static semaphore, failed.
    ");
            rt_sem_detach(&static_sem);//脱离—rt_sem_detach()( 对应静态信号量) ;
            return ;
        }
    
        rt_kprintf("take a staic semaphore, done.
    ");////////////////////////////////////////
    
        /* 脱离信号量对象 */
        rt_sem_detach(&static_sem);//脱离—rt_sem_detach()( 对应静态信号量) ;
    
        /* 2. dynamic semaphore test */
    
        tick = rt_tick_get();
    
        /* 试图持有信号量,最大等待10个OS Tick后返回 */
        result = rt_sem_take(dynamic_sem, 10);
        if (result == -RT_ETIMEOUT)
        {
            /* 超时后判断是否刚好是10个OS Tick */
            if (rt_tick_get() - tick != 10)
            {
                rt_sem_delete(dynamic_sem);
                return ;
            }
            rt_kprintf("take semaphore timeout
    ");/////////////////////////////////////////////////////
        }
        else
        {
            /* 因为没有其他地方释放信号量,所以不应该成功持有信号量,否则测试失败 */
            rt_kprintf("take a dynamic semaphore, failed.
    ");
            rt_sem_delete(dynamic_sem);
            return ;
        }
    
        /* 释放一次信号量 */
        rt_sem_release(dynamic_sem);
    
        /* 永久等待方式持有信号量 */
        result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER);
        if (result != RT_EOK)
        {
            /* 不成功则测试失败 */
            rt_kprintf("take a dynamic semaphore, failed.
    ");
            rt_sem_delete(dynamic_sem);
            return ;
        }
    
        rt_kprintf("take a dynamic semaphore, done.
    ");///////////////////////////////////////////
        /* 删除信号量对象 */
        rt_sem_delete(dynamic_sem);
    }

    演示了静态、动态信号量的各种操作。例程的运行输出如下:

  • 相关阅读:
    jQuery之事件even
    jQuery之动画效果show()......animate()
    jQuery之DOM
    css开发经验&错误习惯
    jQuery语法基础&选择器
    3D案例,导航,导航升级版
    css3实践—创建3D立方体
    CSS3弹性盒模型之Flexbox是布局模块box-sizing & box-orient & box-direction & box-ordinal-group
    Linux-ps命令
    Linux->卸载Mysql方法总结
  • 原文地址:https://www.cnblogs.com/yygsj/p/5502370.html
Copyright © 2011-2022 走看看