RT_Thread内核机制学习(三)进程间通信

队列

在这里插入图片描述
队列里有多个消息块,每个消息块大小一致。
写:

  • 有空间,成功。
  • 无空间:返回Err;等待一段时间。

队列里面会有两个链表:发送链表和接收链表

struct rt_messagequeue
{struct rt_ipc_object parent;                        /**< inherit from ipc_object */void                *msg_pool;                      /**< start address of message queue */rt_uint16_t          msg_size;                      /**< message size of each message */rt_uint16_t          max_msgs;                      /**< max number of messages */rt_uint16_t          entry;                         /**< index of messages in the queue */void                *msg_queue_head;                /**< list head */void                *msg_queue_tail;                /**< list tail */void                *msg_queue_free;                /**< pointer indicated the free node of queue */rt_list_t            suspend_sender_thread;         //挂起的发送线程链表
};
struct rt_ipc_object
{struct rt_object parent;                            /**< inherit from rt_object */rt_list_t        suspend_thread;                    //挂起的接收线程链表
};

在这里插入图片描述
线程2读取mq的数据,如果没有数据,愿意等待5个tick。

  1. 判断队列是否为空?
  2. 判断是否等待?
  3. 线程挂起->从ReadyList移除,放入mq->parent->suspend_thread。
  4. 启动线程自己的定时器
  5. 被唤醒:(1)其它线程写队列,从mq->parent->suspend_thread取出、唤醒(2)超时
struct rt_messagequeue
{struct rt_ipc_object parent;                        /**< inherit from ipc_object */void                *msg_pool;                      /**< start address of message queue */rt_uint16_t          msg_size;                      /**< message size of each message */rt_uint16_t          max_msgs;                      /**< max number of messages */rt_uint16_t          entry;                         //队列中消息的索引void                *msg_queue_head;                /**< list head */void                *msg_queue_tail;                /**< list tail */void                *msg_queue_free;                /**< pointer indicated the free node of queue */rt_list_t            suspend_sender_thread;         /**< sender thread suspended on this message queue */
};
while (mq->entry == 0) //如果消息队列为空{RT_DEBUG_IN_THREAD_CONTEXT;/* reset error number in thread */thread->error = RT_EOK;/* no waiting, return timeout */if (timeout == 0)//不愿意等待{/* enable interrupt */rt_hw_interrupt_enable(temp);thread->error = -RT_ETIMEOUT;return -RT_ETIMEOUT;//立即返回超时错误}/* suspend current thread */rt_ipc_list_suspend(&(mq->parent.suspend_thread),thread,mq->parent.parent.flag); //挂在等待接收链表/* has waiting time, start thread timer */if (timeout > 0){/* get the start tick of timer */tick_delta = rt_tick_get();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));}/* enable interrupt */rt_hw_interrupt_enable(temp);/* re-schedule */rt_schedule();/* recv message */if (thread->error != RT_EOK){/* return error */return thread->error;}/* disable interrupt */temp = rt_hw_interrupt_disable();/* if it's not waiting forever and then re-calculate timeout tick */if (timeout > 0){tick_delta = rt_tick_get() - tick_delta;timeout -= tick_delta;if (timeout < 0)timeout = 0;}
//挂起线程
rt_err_t rt_thread_suspend(rt_thread_t thread)
{register rt_base_t stat;register rt_base_t temp;/* thread check */RT_ASSERT(thread != RT_NULL);RT_ASSERT(rt_object_get_type((rt_object_t)thread) == RT_Object_Class_Thread);RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend:  %s\n", thread->name));stat = thread->stat & RT_THREAD_STAT_MASK;if ((stat != RT_THREAD_READY) && (stat != RT_THREAD_RUNNING)){RT_DEBUG_LOG(RT_DEBUG_THREAD, ("thread suspend: thread disorder, 0x%2x\n",thread->stat));return -RT_ERROR;}/* disable interrupt */temp = rt_hw_interrupt_disable();if (stat == RT_THREAD_RUNNING){/* not suspend running status thread on other core */RT_ASSERT(thread == rt_thread_self());}/* change thread stat */rt_schedule_remove_thread(thread); //从就绪链表中移出thread->stat = RT_THREAD_SUSPEND | (thread->stat & ~RT_THREAD_STAT_MASK);/* stop thread timer anyway */rt_timer_stop(&(thread->thread_timer));/* enable interrupt */rt_hw_interrupt_enable(temp);RT_OBJECT_HOOK_CALL(rt_thread_suspend_hook, (thread));return RT_EOK;
}
RTM_EXPORT(rt_thread_suspend);
由FLAG决定挂起的位置
rt_inline rt_err_t rt_ipc_list_suspend(rt_list_t        *list,struct rt_thread *thread,rt_uint8_t        flag)
{/* suspend thread */rt_thread_suspend(thread);switch (flag){case RT_IPC_FLAG_FIFO: //先进先出,按时间排队rt_list_insert_before(list, &(thread->tlist));break;case RT_IPC_FLAG_PRIO://优先级高的优先{struct rt_list_node *n;struct rt_thread *sthread;/* find a suitable position */for (n = list->next; n != list; n = n->next){sthread = rt_list_entry(n, struct rt_thread, tlist);/* find out */if (thread->current_priority < sthread->current_priority){/* insert this thread before the sthread */rt_list_insert_before(&(sthread->tlist), &(thread->tlist));break;}}/** not found a suitable position,* append to the end of suspend_thread list*/if (n == list)rt_list_insert_before(list, &(thread->tlist));}break;}return RT_EOK;
}
/* has waiting time, start thread timer */if (timeout > 0) //超时时间大于0{/* get the start tick of timer */tick_delta = rt_tick_get();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)); //启动定时器}
rt-schedule();//重新调度,运行其它线程写数据
/* recv message */if (thread->error != RT_EOK) //判断唤醒线程的原因,若是超时错误-ETIMEOUT,则直接返回错误{/* return error */return thread->error;}

写队列

while ((msg = mq->msg_queue_free) == RT_NULL) //队列满了{}
rt_memcpy(msg + 1, buffer, size); //将消息拷贝进Buffer/* resume suspended thread */if (!rt_list_isempty(&mq->parent.suspend_thread)){rt_ipc_list_resume(&(mq->parent.suspend_thread));//唤醒线程/* enable interrupt */rt_hw_interrupt_enable(temp);rt_schedule();return RT_EOK;}
/* disable interrupt */temp = rt_hw_interrupt_disable();/* remove from suspend list */rt_list_remove(&(thread->tlist));rt_timer_stop(&thread->thread_timer);/* enable interrupt */rt_hw_interrupt_enable(temp);/* insert to schedule ready list */rt_schedule_insert_thread(thread);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/94713.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决WebSocket通信:前端拿不到最后一条数据的问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

Redis 哨兵(sentinel)

1. 是什么一 1.1 吹哨人巡查监控后台master主机是否故障&#xff0c;如果故障了根据投票数自动将某一个从库转换为新主库&#xff0c;继续对外服务 1.2 作用 俗称&#xff0c;无人值守运维 哨兵的作用&#xff1a; 1、监控redis运行状态&#xff0c;包括master和slave 2、当m…

Netty-ChannelPipeline

EventLoop可以说是 Netty 的调度中心&#xff0c;负责监听多种事件类型&#xff1a;I/O 事件、信号事件、定时事件等&#xff0c;然而实际的业务处理逻辑则是由 ChannelPipeline 中所定义的 ChannelHandler 完成的&#xff0c;ChannelPipeline 和 ChannelHandler应用开发的过程…

Nginx高级配置

目录 一、Nginx 第三方模块 1.1ehco 模块 二、变量 2.1 内置 2.2 自定义变量 三、nginx压缩功能 ​编辑四、https功能 一、Nginx 第三方模块 1.1ehco 模块 基于nginx 模块 ngx_http_stub_status_module 实现&#xff0c;在编译安装nginx的时候需要添加编译参数 --with-…

Echart笔记

Echart笔记 柱状图带背景色的柱状图将X与Y轴交换制作为进度条 柱状图 带背景色的柱状图 将X与Y轴交换制作为进度条 //将X与Y轴交换制作为进度条 option { xAxis: {type: value,min:0,max:100,show:false,//隐藏x轴},yAxis: {type: category,data:[进度条],show:false,//隐…

iOS开发Swift-6-深色模式,类与对象,MVC模式,弹出框,闭包-趣味问答App

1.创建趣味问答App项目 2.创建一个问题文本&#xff0c;水平居中约束。 创建蓝、红两个按钮&#xff0c;放入Stack View中&#xff0c;给StackView水平居中约束&#xff0c;下边约束&#xff0c;设置两按钮间距为20. 设置进度条view与safe View关系为equal width。设置他们的比…

Nor Flash

核心信息&#xff1a; 工作频率数据吞吐量 bps bit/s&#xff08;传输数据速率&#xff09; Hz&#xff08;时钟频率&#xff09; T/s 56MB/s&#xff08;max&#xff09;448Mb/s&#xff08;数据吞吐量、4路&#xff09;448MHz 112MHz&#xff08;max读、时钟频率&#…

Docker原理详细剖析-Namespace

一、简介 docker容器技术从2013年开始火了以后&#xff0c;2014年左右当时有幸在学校能和学院教授一起做些项目以及学习。其中docker技术在当时来说还算是比较新的技术&#xff0c;国内关于这块的资料以及使用也才刚刚开始&#xff0c;讨论docker技术&#xff0c;算是相对时髦的…

【Nacos】使用Nacos进行服务发现、配置管理

Nacos Nacos是 Dynamic Naming and Configuration Service 的首字母简称&#xff0c;一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。 版本说明&#xff1a;版本说明 alibaba/spring-cloud-alibaba Wiki GitHub <properties><java.version>…

NFT Insider#105:The Sandbox即将参加韩国区块链周,YGG的声誉和进步(RAP)将引领玩家晋升到下一层级

引言&#xff1a;NFT Insider由NFT收藏组织WHALE Members(https://twitter.com/WHALEMembers)、BeepCrypto&#xff08;https://twitter.com/beep_crypto&#xff09;联合出品&#xff0c;浓缩每周NFT新闻&#xff0c;为大家带来关于NFT最全面、最新鲜、最有价值的讯息。每期周…

Windows安装配置Rust(附CLion配置与运行)

Windows安装配置Rust&#xff08;附CLion配置与运行&#xff09; 前言一、下载二、安装三、配置标准库&#xff01;&#xff01;&#xff01;四、使用 CLion 运行 rust1、新建rust项目2、配置运行环境3、运行 前言 本文以 windows 安装为例&#xff0c;配置编译器为 minGW&…

腾讯云国际代充-GPU服务器安装驱动教程NVIDIA Tesla

腾讯云国际站GPU 云服务器是基于 GPU 的快速、稳定、弹性的计算服务&#xff0c;主要应用于深度学习训练/推理、图形图像处理以及科学计算等场景。 GPU 云服务器提供和标准腾讯云国际 CVM 云服务器一致的方便快捷的管理方式。 GPU 云服务器通过其强大的快速处理海量数据的计算性…