RT_Thread内核机制学习(六)信号量

这篇具有很好参考价值的文章主要介绍了RT_Thread内核机制学习(六)信号量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

要传输较大数据时,使用队列。
传输较小数值时,使用邮箱。

队列、邮箱用来传递数据。
如果只是用来传递资源的个数,可以使用信号量。

RT_Thread内核机制学习(六)信号量,RT-Thread,学习,RT-Thread
A车与B车只需要传递信号量(代表资源)。

信号量

获取信号量

  1. 如果value>0,value–,return OK;如果value0,timeout0,return -ETIMEOUT;如果value==0,timeout>0,从就绪链表移除(挂起),把自己记录在信号量的等待链表。
  2. 被唤醒:如果thread->err!=0,return thread->err;return EOK;

释放信号量

  1. value++;如果有等待信号量线程,唤醒线程。

创建信号量

/**
 * This function will create a semaphore from system resource
 *
 * @param name the name of semaphore
 * @param value the initial value of semaphore
 * @param flag the flag of semaphore
 *
 * @return the created semaphore, RT_NULL on error happen
 *
 * @see rt_sem_init
 */
rt_sem_t rt_sem_create(const char *name, rt_uint32_t value, rt_uint8_t flag)

信号量结构体

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

struct rt_ipc_object
{
    struct rt_object parent;                            /**< inherit from rt_object */

    rt_list_t        suspend_thread;                    /**< threads pended on this resource */
};

获取信号量

rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time)
{
    register rt_base_t temp;
    struct rt_thread *thread;

    /* parameter check */
    RT_ASSERT(sem != RT_NULL);
    RT_ASSERT(rt_object_get_type(&sem->parent.parent) == RT_Object_Class_Semaphore);

    RT_OBJECT_HOOK_CALL(rt_object_trytake_hook, (&(sem->parent.parent)));

    /* disable interrupt */
    temp = rt_hw_interrupt_disable(); //关中断

    RT_DEBUG_LOG(RT_DEBUG_IPC, ("thread %s take sem:%s, which value is: %d\n",
                                rt_thread_self()->name,
                                ((struct rt_object *)sem)->name,
                                sem->value));

    if (sem->value > 0) //如果有资源
    {
        /* semaphore is available */
        sem->value --;

        /* enable interrupt */
        rt_hw_interrupt_enable(temp);
    }
    else
    {
        /* no waiting, return with timeout */
        if (time == 0)
        {
            rt_hw_interrupt_enable(temp);

            return -RT_ETIMEOUT;
        }
        else
        {
            /* current context checking */
            RT_DEBUG_IN_THREAD_CONTEXT;

            /* semaphore is unavailable, push to suspend list */
            /* get current thread */
            thread = rt_thread_self();

            /* reset thread error number */
            thread->error = RT_EOK;

            RT_DEBUG_LOG(RT_DEBUG_IPC, ("sem take: suspend thread - %s\n",
                                        thread->name));

            /* suspend thread */
            rt_ipc_list_suspend(&(sem->parent.suspend_thread),
                                thread,
                                sem->parent.parent.flag);

            /* has waiting time, start thread timer */
            if (time > 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,
                                 &time);
                rt_timer_start(&(thread->thread_timer));
            }

            /* enable interrupt */
            rt_hw_interrupt_enable(temp);

            /* do schedule */
            rt_schedule();

            if (thread->error != RT_EOK)
            {
                return thread->error;
            }
        }
    }

    RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(sem->parent.parent)));

    return RT_EOK; //获取到了资源成功返回
}
RTM_EXPORT(rt_sem_take);

释放信号量

rt_err_t rt_sem_release(rt_sem_t sem)
{
    register rt_base_t temp;
    register rt_bool_t need_schedule;

    /* parameter check */
    RT_ASSERT(sem != RT_NULL);
    RT_ASSERT(rt_object_get_type(&sem->parent.parent) == RT_Object_Class_Semaphore);

    RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(sem->parent.parent)));

    need_schedule = RT_FALSE;

    /* disable interrupt */
    temp = rt_hw_interrupt_disable();

    RT_DEBUG_LOG(RT_DEBUG_IPC, ("thread %s releases sem:%s, which value is: %d\n",
                                rt_thread_self()->name,
                                ((struct rt_object *)sem)->name,
                                sem->value));

    if (!rt_list_isempty(&sem->parent.suspend_thread)) //是否有等待线程
    {
        /* resume the suspended thread */
        rt_ipc_list_resume(&(sem->parent.suspend_thread));//唤醒++,接收--,所以没有对sem->value做任何操作。
        need_schedule = RT_TRUE;
    }
    else
        sem->value ++; /* increase value */

    /* enable interrupt */
    rt_hw_interrupt_enable(temp);

    /* resume a thread, re-schedule */
    if (need_schedule == RT_TRUE)
        rt_schedule();

    return RT_EOK;
}
RTM_EXPORT(rt_sem_release);

RT_Thread内核机制学习(六)信号量,RT-Thread,学习,RT-Thread文章来源地址https://www.toymoban.com/news/detail-684647.html

到了这里,关于RT_Thread内核机制学习(六)信号量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【STM32】FreeRTOS消息队列和信号量学习

    一、消息队列(queue) 队列是一种用于实现任务与任务之间,任务与中断之间消息交流的机制。 注意:1.数据的操作是FIFO模式。 2.队列需要明确数据的大小和队列的长度。 3.写和读都会出现堵塞。 实验:创建一个消息队列,两个发送任务,一个接收任务。 其中任务一任务三

    2024年02月13日
    浏览(39)
  • 学习系统编程No.22【消息队列和信号量】

    北京时间:2023/4/20/7:48,闹钟6点和6点30,全部错过,根本起不来,可能是因为感冒还没好,睡不够吧!并且今天是星期四,这个星期这是第二篇博客,作为一个日更选手,少些了两篇博客,充分摆烂,但是摆烂具体也是有原因的,星期一的时候莫名高烧,头昏脑涨的感觉,睡

    2023年04月27日
    浏览(41)
  • 关于RT_thread延时函数的分析

      一些基本的定义     任何操作系统都需要提供一个时钟节拍,以供系统处理所有和时间有关的事件,如线程的延时、线程的时间片轮转调度以及定时器超时等。时钟节拍是特定的周期性中断,这个中断可以看做是系统心跳,中断之间的时间间隔取决于不同的应用,一般是

    2024年02月16日
    浏览(33)
  • 嵌入式实时操作系统的设计与开发(信号量学习)

    除了临界点机制、互斥量机制可实现临界资源的互斥访问外,信号量(Semaphore)是另一选择。 信号量与互斥量的区别 对于互斥量来说,主要应用于临界资源的互斥访问,并且能够有效地避免优先级反转问题。 对于信号量而言,它虽然也能用于临界资源的互斥访问,但是不能

    2024年02月08日
    浏览(55)
  • 【Linux学习】多线程——信号量 | 基于环形队列的生产者消费者模型 | 自旋锁 | 读写锁

    🐱作者:一只大喵咪1201 🐱专栏:《Linux学习》 🔥格言: 你只管努力,剩下的交给时间! 之前在学习进程间通信的时候,本喵简单的介绍过一下信号量,今天在这里进行详细的介绍。 这是之前写的基于阻塞队列的生产者消费者模型中向阻塞队列中push任务的代码。 上面代码

    2024年02月07日
    浏览(54)
  • 全网最详细STM32在RT_thread中配置spi并成功使用

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 @[TOC]SPI通信 在自身学习时查找资料,没有一个系统的在RT中实现spi并测试的,都是进行ID的读写简单操作,因此在学习完后准备记录系统的一个学习spi的过程,配有详细源码,看完包会!!! 结合自身学

    2024年01月16日
    浏览(27)
  • 【Linux C | 多线程编程】线程同步 | 信号量(无名信号量) 及其使用例子

    😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭 🤣本文内容🤣:🍭介绍 🍭 😎金句分享😎:🍭你不能选择最好的,但最好的会来选择你——泰戈尔🍭 ⏰发布时间⏰: 本文未经允许,不得转发!!!

    2024年04月26日
    浏览(37)
  • 【Linux从入门到精通】信号量(信号量的原理与相关操作接口)详解

      本篇文章重点对 信号量的概念,信号量的申请、初始化、释放、销毁等操作进行讲解。同时举例把信号量应用到生产者消费者模型来理解 。希望本篇文章会对你有所帮助。 目录 一、信号量概念 1、1 什么是信号量 1、2 为什么要有信号量 1、3 信号量的PV操作 二、信号量的相

    2024年02月08日
    浏览(47)
  • uCOSii信号量

    uCOSii 信号量 主要用来测试使用uCOSii“创建信号量,发送信号量,接收信号量,删除信号量”。 学习uCOSii一定要先了解os_cfg.h文件。 信号量管理函数如下: OSSemAccept () 无条件地等待请求一个信号量函数,中断服务子程序只能用OSSemAccept()而不能用OSSemPend(),因为中断服务子程序是不

    2024年02月07日
    浏览(55)
  • 信号量

    信号量(semaphore)和信号只有一字之差,却是不同的概念, 信号量与之前介绍的IPC不同,它是一个计数器,用于实现进程间的互斥于同步 本文参考: Linux 的信号量_linux 信号量_行孤、的博客-CSDN博客 【Linux】Linux的信号量集_Yngz_Miao的博客-CSDN博客 Linux进程间通信(九)——信

    2024年02月12日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包