RT-Thread学习记录7 信号量的使用

旧巷老猫 提交于 2020-10-23 17:37:31

以下为看视频笔记..........

1. 信号量(IPC)

在嵌入式系统中运行的代码主要包括线程和中断(ISR),在它们的运行过程中,它们的运行步骤有时需要同步(按照预定的先后次序运行),它们访问的资源有时需要互斥(一个时刻只允许一个线程访问资源),它们之间有时也要彼此交换数据。这些需求,有的是因为应用需求,有的是多线程编程模型带来的需求。

操作系统必须提供相应的机制来完成这些功能,我们把这些机制统称为进(线)程间通信(Internal Process Communication IPC) ,RT-Thread中的IPC机制包括信号量、互斥量、事件、邮箱、消息队列。
.
通过IPC机制,我们可以协调多个线程(包括ISR)“默契”的工作,从而共同完成一个整项工作。



2. 例子说信号量

以生活中的停车场为例来理解信号量的概念:

①当停车场空的时候,停车场的管理员发现有很多空车位,此时会让外面的车陆续进入停车场获得停车位;

②当停车场的车位满的时候,管 理员发现已经没有空车位,将禁止外面的车进入停车场,车辆在外排队等候;

③当停车场内有车离开时,管理员发现有空的车位让出,允许外面的车进入停车场;待空车位填满后,又禁止外部车辆进入。

在此例子中,管理员就相当于信号量;管理员手中空车位的个数就是信号量的值;停车位相当于公共资源,车辆相当于线程。车辆通过 获得管理员的允许取得停车位,就类似于线程通过获得信号量访问公共资源







3. 信号量工作机制

信号量是--种轻型的用于解决线程间同步问题的内核对象,线程可以获取或释放它,从而达到同步或互斥的目的。

信号量工作示意图如.上图所示,每个信号量对象都有一个信号量值和一个线程等待队列,信号量的值对应信号量对象的实例数目(资源数目),假如信号量值N,则表示共有N个信号量实例(资源)可以被使用,当信号量实例数目为零时,再请该信号量的线程就会被挂起在该信号量的等待队列上,等待可用的信号量实例(资源)

4. 信号量数据块

在RT-Thread中,信号量控制块是操作系统用于管理信号量的一个数据结构

struct rt_semaphore 
{
    struct rt_ipc_object  parent;
    
    rt_uint16_t           value;  //信号量的有效值

}

定义静态信号量:struct  rt_semaphore   static_sem

定义动态信号量:rt_sem_t    dynamic_sem 

类似动态线程和静态线程

5. 信号量的操作

初始化与脱离

rt_err_t  rt_sem_init( rt_sem_t  sem,      //信号量指针
                       const char  *name,  //信号量的名称
                       rt_uint32_t value,  //初始化结构体里的value
                       rt_uint8_t  flag)  
 //flag可为RT_IPC_FLAG_FIFO,即线程等待信号的方式为先进先出排队(先到先得)
//RT_IPC_FLAG_PRIO即线程等待信号的方式为线程优先级排队
 
rt_err_t rt_sem_detach(rt_sem_t sem)
//这两个API是用于创建静态信号量

创建与删除

rt_sem_t  rt_sem_create(const char *name,
                        rt_uint32_t  value,
                        rt_uint8_t  flag)

rt_err_t rt_sem_delete(rt_sem_t  sem)
//这两个API是用于创建动态信号量,因为是动态创建要用返回值rt_sem_tl来判断动态创建是否成功  

获取信号量

先把信号量的指针rt_sem_t 传给函数,说明要获取信号量,当获取到信号量时value值减一,当value值为零时说明共享资源不可用。当time为零时,会立刻返回,当time为大于零时,根据time值的时间之后返回,一系统滴答为时间单位。当time值为负数时,

用宏RT_WAITING_FOREVER表示,线程永远在这个信号量上做等待。

rt_err_t  rt_sem_take(rt_sem_t  sem,rt_int32_t  time)
//rt_sem_take()只能在线程中调用等待信号量,不能在中断中使用,会导致挂起,否则得不到返回值
rt_err_t rt_sem_trytake(rt_sem_t  sem) 
//和上一个比较时间参数为0,即不做任何的等待,能获得信号量就返回,不能获得就返回-RT_TIMEOUT所以在使用时要判断返回值是否获得了信号量,还是超时了。

释放信号量

rt_err_t  rt_sem_release(rt_sem_t  sem)
//对共享资源value加一,可以在线程和中断中释放信号量

6.信号量的使用

在实例代码中的semaphore_sample.c中

 

 

 

 

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!