RT-Thread 线程间通信 信号量

信号量的功能其实很简单,就是记录某个资源还剩余多少的数量

一个线程运行的时候,如果需要某个资源,就会来询问这个资源还有多少,这个信号量就是记录资源的数量

当线程使用这个资源的时候,就会获取这个信号量,会让这个信号量--,

当线程使用完之后,不再需要资源了,就要释放信号量,让信号量++。

1、获取信号量

获取信号量:

        有信号量:成功

        没有信号量:等待?

                不等待:返回失败

                等待:

                        将自己从readylist移除

                        将自己挂载在信号量的链表中

2、释放信号量

信号量++

如果信号量链表上有线程,唤醒这些线程

信号量结构体:

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 */
};

重要的就是value,表示信号量的数量。

分析代码:

1、创建信号量:

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

2、删除信号量:

rt_err_t rt_sem_detach(rt_sem_t sem)
rt_err_t rt_sem_delete(rt_sem_t sem)

3、获取信号量:

rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t timeout)

 获取信号量,如果信号量还有,直接获取就可以

if (sem->value > 0)
{
        sem->value --;                                 /* semaphore is available */
        rt_hw_interrupt_enable(level);         /* enable interrupt */
}

没有信号量,且不愿意等待,返回错误

if (timeout == 0)
{
        rt_hw_interrupt_enable(level);

        return -RT_ETIMEOUT;
}

没有信号量,愿意等待:

将自己从readylist链表里面移除,挂在信号量的链表里面,开启线程的定时器

_ipc_list_suspend(&(sem->parent.suspend_thread),
                                thread,
                                sem->parent.parent.flag);

/* has waiting time, start thread timer */
if (timeout > 0)
{
        RT_DEBUG_LOG(RT_DEBUG_IPC, ("set thread:%s to timer list\n",thread->name));

        /* reset the timeout of thread timer and start it */
        rt_timer_control(&(thread->thread_timer),RT_TIMER_CTRL_SET_TIME,&timeout);
        rt_timer_start(&(thread->thread_timer));
}

超时后,返回超时。

4、释放信号量

rt_err_t rt_sem_release(rt_sem_t sem)

释放信号量,不止是将信号量++,中间还有一些其他的操作:

查看信号量的链表里面有没有等待信号量挂起的线程,唤醒这些等待的线程。

if (!rt_list_isempty(&sem->parent.suspend_thread))
{
        _ipc_list_resume(&(sem->parent.suspend_thread)); /* resume the suspended thread */
        need_schedule = RT_TRUE;
}

之后再释放信号量,信号量++。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值