8.信号量的使用

信号量

​ 注意信号量和信号没有关系,信号是用来通知的,信号量则表示资源的数量,支持的动作:"give"给出资源,计数值加 1;"take"获得资源,计数值减 1。

​ 在rtt中,使用使用结构体 struct rt_semaphore 来管理信号量,成员 rt_uint16_t value 表示信号量的值,最大为 65535。:

struct rt_semaphore
{
 struct rt_ipc_object parent; /**< inherit from ipc_object */
 rt_uint16_t value; /**< value of semaphore. */
 rt_uint16_t reserved; /**< reserved field */
};

​ 在使用信号量时,先创建/初始化、然后去获取资源、释放资源。使用句柄 rt_sem_t 来表示一个信号量

创建/初始化:使用信号量之前,要先创建,得到一个句柄;使用信号量时,要使用句柄来表明使用哪个信号量。信号量的创建有两种方法:动态分配内存rt_sem_create()、静态分配内存rt_sem_init(),

rt_sem_t rt_sem_create(const char *name,rt_uint32_t value,rt_uint8_t flag)
rt_err_t rt_sem_init(rt_sem_t sem,const char *name,rt_uint32_t value,rt_uint8_t flag)
//其中flag的用法和消息队列中一样,可取RT_IPC_FLAG_FIFO 和 RT_IPC_FLAG_PRIO

删除/脱离:不再使用一个信号量时,删除它:rt_sem_delete();脱离它:rt_sem_detach()

删除消息队列的函数为 rt_sem_delete(),它会释放内存。删除信号量时,如果有线程正在等待该信号量,则内核会先唤醒这些线程(线程返回值是 - RT_ERROR),然后再释放信号量使用的内存,最后删除信号量对象。原型如下:

rt_err_t rt_sem_delete(rt_sem_t sem);

脱离信号量,就是将信号量对象被从内核对象管理器中脱离。脱离信号量时,如果有线程在等待该信号量,则内核会先唤醒这些线程。原型如下:

rt_err_t rt_sem_detach(rt_sem_t sem)

获取/释放:RT-Thread 有两个获取信号量的函数,一个释放信号量函数:rt_sem_take() 获取信号量,rt_sem_trytake() 无等待、尝试获取信号量,rt_sem_release() 释放信号量。

  • 使用 rt_sem_take()获取信号量时,信号量的值大于 0,线程将获得信号量,信号量值减 1;当信号量的值等于 0 时,线程会根据 timeout 参数等待,超时后才返回错误( -RT_ETIMEOUT)
  • 使用 rt_sem_trytake()获取信号量时,信号量的值大于 0,线程将获得信号量,信号量值减 1;当信号量的值等于 0 时,线程会直接返回,和 rt_sem_take(sem, RT_WAITING_NO)作用相同,即不会等待。
  • 使用 rt_sem_release()将释放信号量:如果有线程在等待这个信号量,此函数不会累加信号量的值,而是直接唤醒等待的线程(唤醒顺序和flag有关),如果没有线程在等待这个信号量,此函数会累加信号量的值

获取信号量的函数原型如下:

rt_err_t rt_sem_take (rt_sem_t sem, rt_int32_t time);
time:超时时间,单位为系统时钟节拍(OS Tick)

无等待获取信号量的函数原型如下:

rt_err_t rt_sem_trytake(rt_sem_t sem);

释放信号量的函数原型如下:

rt_err_t rt_sem_release(rt_sem_t sem);
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值