μC/OS-II---消息队列管理2(os_q.c)

目录

  • 消息队列的主要优点
  • 消息队列和消息邮箱
  • 消息队列相关操作
    • 向消息队列发送消息(FIFO)
    • 向消息队列发送消息(LIFO)
    • 向消息队列发送消息(扩展)
    • 消息队列获取/无等待
    • 清空消息队列
    • 消息队列信息获取
    • 消息队列中断等待

在这里插入图片描述

消息队列的主要优点

  • 消息队列的主要优点是解耦和异步通信。发送者和接收者之间不需要直接建立连接,它们只需要知道消息队列的名称或标识符即可。发送者将消息发送到队列中后,可以继续执行其他任务,而不需要等待接收者处理消息。接收者可以在合适的时候从队列中获取消息进行处理,这样可以实现异步通信,提高系统的并发性和响应性。
  • 通常会在消息队列中引入消息标识符或者消息类型。发送者在发送消息时,会附带一个标识符或类型,接收者在接收消息时,会根据标识符或类型来判断是否是自己需要处理的消息。这样可以确保每个进程只处理属于自己的消息,避免了拿错信息的问题。
  • 此外,还可以使用互斥锁或其他同步机制来保证在读取和写入消息队列时的原子性操作,避免多个进程同时对消息队列进行读写操作而导致的竞争条件。

消息队列和消息邮箱

  • 消息队列是一个独立的数据结构,多个进程可以共享同一个消息队列,而消息邮箱是与进程关联的,每个进程都有自己的邮箱。此外,消息队列通常是先进先出(FIFO)的,而消息邮箱可以根据实现方式不同具有不同的特性,比如可以是先进先出或者按优先级处理消息。
  • Task也可以设计有“私有”消息队列模式。
  • 总的来说,消息队列更适合实现多个进程之间的解耦和异步通信,而消息邮箱更适合实现单个进程内的消息传递。

消息队列相关操作

向消息队列发送消息(FIFO)

#if OS_Q_POST_EN > 0u
INT8U  OSQPost (OS_EVENT  *pevent,void      *pmsg)
{OS_Q      *pq;
#if OS_CRITICAL_METHOD == 3u                           /* Allocate storage for CPU status register     */OS_CPU_SR  cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                       /* Validate 'pevent'                            */{return (OS_ERR_PEVENT_NULL);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q)        /* Validate event block type                    */{return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();if (pevent->OSEventGrp != 0u)                      /* See if any task pending on queue             */{/* Ready highest priority task waiting on event */(void)OS_EventTaskRdy (pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK);OS_EXIT_CRITICAL();OS_Sched();                                    /* Find highest priority task ready to run      */return (OS_ERR_NONE);}pq = (OS_Q *)pevent->OSEventPtr;                   /* Point to queue control block                 */if (pq->OSQEntries >= pq->OSQSize)                 /* Make sure queue is not full                  */{OS_EXIT_CRITICAL();return (OS_ERR_Q_FULL);}*pq->OSQIn++ = pmsg;                               /* Insert message into queue                    */pq->OSQEntries++;                                  /* Update the nbr of entries in the queue       */if (pq->OSQIn == pq->OSQEnd)                       /* Wrap IN ptr if we are at end of queue        */{pq->OSQIn = pq->OSQStart;}OS_EXIT_CRITICAL();return (OS_ERR_NONE);
}
#endif

向消息队列发送消息(LIFO)

#if OS_Q_POST_FRONT_EN > 0u
INT8U  OSQPostFront (OS_EVENT  *pevent,void      *pmsg)
{OS_Q      *pq;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */OS_CPU_SR  cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                      /* Validate 'pevent'                             */{return (OS_ERR_PEVENT_NULL);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q)       /* Validate event block type                     */{return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();if (pevent->OSEventGrp != 0u)                     /* See if any task pending on queue              */{/* Ready highest priority task waiting on event  */(void)OS_EventTaskRdy (pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK);OS_EXIT_CRITICAL();OS_Sched();                                   /* Find highest priority task ready to run       */return (OS_ERR_NONE);}pq = (OS_Q *)pevent->OSEventPtr;                  /* Point to queue control block                  */if (pq->OSQEntries >= pq->OSQSize)                /* Make sure queue is not full                   */{OS_EXIT_CRITICAL();return (OS_ERR_Q_FULL);}if (pq->OSQOut == pq->OSQStart)                   /* Wrap OUT ptr if we are at the 1st queue entry */{pq->OSQOut = pq->OSQEnd;}pq->OSQOut--;*pq->OSQOut = pmsg;                               /* Insert message into queue                     */pq->OSQEntries++;                                 /* Update the nbr of entries in the queue        */OS_EXIT_CRITICAL();return (OS_ERR_NONE);
}
#endif

向消息队列发送消息(扩展)

#if OS_Q_POST_OPT_EN > 0u
INT8U  OSQPostOpt (OS_EVENT  *pevent,void      *pmsg,INT8U      opt)
{OS_Q      *pq;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */OS_CPU_SR  cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                      /* Validate 'pevent'                             */{return (OS_ERR_PEVENT_NULL);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q)       /* Validate event block type                     */{return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();if (pevent->OSEventGrp != 0x00u)                  /* See if any task pending on queue              */{if ((opt & OS_POST_OPT_BROADCAST) != 0x00u)   /* Do we need to post msg to ALL waiting tasks ? */{while (pevent->OSEventGrp != 0u)          /* Yes, Post to ALL tasks waiting on queue       */{(void)OS_EventTaskRdy (pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK);}}else                                          /* No,  Post to HPT waiting on queue             */{(void)OS_EventTaskRdy (pevent, pmsg, OS_STAT_Q, OS_STAT_PEND_OK);}OS_EXIT_CRITICAL();if ((opt & OS_POST_OPT_NO_SCHED) == 0u)       /* See if scheduler needs to be invoked          */{OS_Sched();                               /* Find highest priority task ready to run       */}return (OS_ERR_NONE);}pq = (OS_Q *)pevent->OSEventPtr;                  /* Point to queue control block                  */if (pq->OSQEntries >= pq->OSQSize)                /* Make sure queue is not full                   */{OS_EXIT_CRITICAL();return (OS_ERR_Q_FULL);}if ((opt & OS_POST_OPT_FRONT) != 0x00u)           /* Do we post to the FRONT of the queue?         */{if (pq->OSQOut == pq->OSQStart)               /* Yes, Post as LIFO, Wrap OUT pointer if we ... */{pq->OSQOut = pq->OSQEnd;                  /*      ... are at the 1st queue entry           */}pq->OSQOut--;*pq->OSQOut = pmsg;                           /*      Insert message into queue                */}else                                              /* No,  Post as FIFO                             */{*pq->OSQIn++ = pmsg;                          /*      Insert message into queue                */if (pq->OSQIn == pq->OSQEnd)                  /*      Wrap IN ptr if we are at end of queue    */{pq->OSQIn = pq->OSQStart;}}pq->OSQEntries++;                                 /* Update the nbr of entries in the queue        */OS_EXIT_CRITICAL();return (OS_ERR_NONE);
}
#endif

消息队列获取/无等待

#if OS_Q_ACCEPT_EN > 0u
void  *OSQAccept (OS_EVENT  *pevent,INT8U     *perr)
{void      *pmsg;OS_Q      *pq;
#if OS_CRITICAL_METHOD == 3u                     /* Allocate storage for CPU status register           */OS_CPU_SR  cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICALif (perr == (INT8U *)0){OS_SAFETY_CRITICAL_EXCEPTION();return ((void *)0);}#endif
#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                 /* Validate 'pevent'                                  */{*perr = OS_ERR_PEVENT_NULL;return ((void *)0);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q)  /* Validate event block type                          */{*perr = OS_ERR_EVENT_TYPE;return ((void *)0);}OS_ENTER_CRITICAL();pq = (OS_Q *)pevent->OSEventPtr;             /* Point at queue control block                       */if (pq->OSQEntries > 0u)                     /* See if any messages in the queue                   */{pmsg = *pq->OSQOut++;                    /* Yes, extract oldest message from the queue         */pq->OSQEntries--;                        /* Update the number of entries in the queue          */if (pq->OSQOut == pq->OSQEnd)            /* Wrap OUT pointer if we are at the end of the queue */{pq->OSQOut = pq->OSQStart;}*perr = OS_ERR_NONE;}else{*perr = OS_ERR_Q_EMPTY;pmsg  = (void *)0;                       /* Queue is empty                                     */}OS_EXIT_CRITICAL();return (pmsg);                               /* Return message received (or NULL)                  */
}
#endif

清空消息队列

#if OS_Q_FLUSH_EN > 0u
INT8U  OSQFlush (OS_EVENT *pevent)
{OS_Q      *pq;
#if OS_CRITICAL_METHOD == 3u                          /* Allocate storage for CPU status register      */OS_CPU_SR  cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                      /* Validate 'pevent'                             */{return (OS_ERR_PEVENT_NULL);}if (pevent->OSEventType != OS_EVENT_TYPE_Q)       /* Validate event block type                     */{return (OS_ERR_EVENT_TYPE);}#endifOS_ENTER_CRITICAL();pq             = (OS_Q *)pevent->OSEventPtr;      /* Point to queue storage structure              */pq->OSQIn      = pq->OSQStart;pq->OSQOut     = pq->OSQStart;pq->OSQEntries = 0u;OS_EXIT_CRITICAL();return (OS_ERR_NONE);
}
#endif

消息队列信息获取

#if OS_Q_QUERY_EN > 0u
INT8U  OSQQuery (OS_EVENT  *pevent,OS_Q_DATA *p_q_data)
{OS_Q       *pq;INT8U       i;OS_PRIO    *psrc;OS_PRIO    *pdest;
#if OS_CRITICAL_METHOD == 3u                           /* Allocate storage for CPU status register     */OS_CPU_SR   cpu_sr = 0u;
#endif
#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                       /* Validate 'pevent'                            */{return (OS_ERR_PEVENT_NULL);}if (p_q_data == (OS_Q_DATA *)0)                    /* Validate 'p_q_data'                          */{return (OS_ERR_PDATA_NULL);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q)        /* Validate event block type                    */{return (OS_ERR_EVENT_TYPE);}OS_ENTER_CRITICAL();p_q_data->OSEventGrp = pevent->OSEventGrp;         /* Copy message queue wait list                 */psrc                 = &pevent->OSEventTbl[0];pdest                = &p_q_data->OSEventTbl[0];for (i = 0u; i < OS_EVENT_TBL_SIZE; i++){*pdest++ = *psrc++;}pq = (OS_Q *)pevent->OSEventPtr;if (pq->OSQEntries > 0u){p_q_data->OSMsg = *pq->OSQOut;                 /* Get next message to return if available      */}else{p_q_data->OSMsg = (void *)0;}p_q_data->OSNMsgs = pq->OSQEntries;p_q_data->OSQSize = pq->OSQSize;OS_EXIT_CRITICAL();return (OS_ERR_NONE);
}
#endif

消息队列中断等待

#if OS_Q_PEND_ABORT_EN > 0u
INT8U  OSQPendAbort (OS_EVENT  *pevent,INT8U      opt,INT8U     *perr)
{INT8U      nbr_tasks;
#if OS_CRITICAL_METHOD == 3u                               /* Allocate storage for CPU status register */OS_CPU_SR  cpu_sr = 0u;
#endif
#ifdef OS_SAFETY_CRITICALif (perr == (INT8U *)0){OS_SAFETY_CRITICAL_EXCEPTION();return (0u);}#endif
#if OS_ARG_CHK_EN > 0uif (pevent == (OS_EVENT *)0)                           /* Validate 'pevent'                        */{*perr = OS_ERR_PEVENT_NULL;return (0u);}#endifif (pevent->OSEventType != OS_EVENT_TYPE_Q)            /* Validate event block type                */{*perr = OS_ERR_EVENT_TYPE;return (0u);}OS_ENTER_CRITICAL();if (pevent->OSEventGrp != 0u)                          /* See if any task waiting on queue?        */{nbr_tasks = 0u;switch (opt){case OS_PEND_OPT_BROADCAST:                    /* Do we need to abort ALL waiting tasks?   */while (pevent->OSEventGrp != 0u)          /* Yes, ready ALL tasks waiting on queue    */{(void)OS_EventTaskRdy (pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT);nbr_tasks++;}break;case OS_PEND_OPT_NONE:default:                                       /* No,  ready HPT       waiting on queue    */(void)OS_EventTaskRdy (pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT);nbr_tasks++;break;}OS_EXIT_CRITICAL();OS_Sched();                                        /* Find HPT ready to run                    */*perr = OS_ERR_PEND_ABORT;return (nbr_tasks);}OS_EXIT_CRITICAL();*perr = OS_ERR_NONE;return (0u);                                           /* No tasks waiting on queue                */
}
#endif

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

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

相关文章

git push 报错 The requested URL returned error: 500

今天gitpush时报错The requested URL returned error: 500 看报错应该是本地和gitlab服务器之间通信的问题&#xff0c;登录gitlab网站查看 登录时报错无法通过ldapadmin认证&#xff0c;ldap服务器连接失败。 首先&#xff0c;登录ldap服务器&#xff0c;查看是否是ldap服务…

Python爬虫从基础到入门:找数据接口

Python爬虫从基础到入门:找数据接口 1. 怎样判断抓取的数据是动态生成的2. 用requests模块访问,然后用解析模块解析数据3. 总结1. 怎样判断抓取的数据是动态生成的 请参考文章:Python爬虫从基础到入门:认识爬虫 第3点所讲。 这里用我的CSDN个人主页举例。 可以说这部分下的…

微信公众号上怎么做电子优惠券

在当今的数字化时代&#xff0c;微信公众号已经成为企业与消费者之间的重要桥梁。然而&#xff0c;如何才能让你的公众号更加吸引人&#xff0c;提高粉丝转化率呢&#xff1f;今天&#xff0c;我们将为你揭示一个秘密武器——电子优惠券&#xff01;通过巧妙地运用电子优惠券&a…

2013年11月26日 Go生态洞察:Go中的文本规范化

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

在对话式体验中探索生成式AI:Amazon Lex、Langchain和Amazon SageMaker Jumpstart简介

在当今快节奏的世界里&#xff0c;客户希望企业提供快速高效的服务。但是&#xff0c;当咨询量超过了处理这些咨询所需的人力资源时&#xff0c;提供优质客户服务就会面临巨大挑战。然而&#xff0c;借助由大型语言模型&#xff08;LLM&#xff09;支持的生成式 AI 的进步&…

【深度学习 | 核心概念】那些深度学习路上必经的核心概念,确定不来看看? (六)

&#x1f935;‍♂️ 个人主页: AI_magician &#x1f4e1;主页地址&#xff1a; 作者简介&#xff1a;CSDN内容合伙人&#xff0c;全栈领域优质创作者。 &#x1f468;‍&#x1f4bb;景愿&#xff1a;旨在于能和更多的热爱计算机的伙伴一起成长&#xff01;&#xff01;&…

基于JavaWeb的网上体育商城的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。你想解决的问题&#xff0c;今天给大家介绍…

【保姆级教程】Linux安装JDK8

本文以centos7为例&#xff0c;一步一步进行jdk1.8的安装。 1. 下载安装 官网下载链接&#xff1a; https://www.oracle.com/cn/java/technologies/downloads/#java8 上传jdk的压缩包到服务器的/usr/local目录下 在当前目录解压jdk压缩包&#xff0c;如果是其它版本&#xf…

格式工厂——万能格式转换器

很多时候&#xff0c;大家从网络上下载的文件不一定是自己想要的类型&#xff0c;比如flv等视频文件&#xff0c;而强行改文件后缀名只会造成文件格式错误&#xff0c;无法打开&#xff1b;而很多文件的格式并不能轻易转换&#xff0c;且很多渠道都需要收费。今天介绍的这款For…

MySQL中全文索引和普通索引的区别

MySQL中的全文索引&#xff08;Full-Text Index&#xff09;和普通索引&#xff08;比如B-Tree索引&#xff09;是为了提高查询效率而设计的&#xff0c;但它们适用于不同的场景和查询类型。 普通索引&#xff08;如B-Tree索引&#xff09; 适用场景&#xff1a;普通索引适用于…

自动备份pgsql数据库

bat文件中的内容&#xff1a; PATH D:\Program Files\PostgreSQL\13\bin;D:\Program Files\7-Zip set PGPASSWORD**** pg_dump -h 8.134.151.187 -p 5466 -U sky -d mip_db --schema-only -f D:\DB\backup\%TODAY%-schema-mip_db_ali.sql pg_dump -h 8.134.151.187 -p 5466…

工业除尘器笔记

工业除尘器用于对工业生产产生的有害气体和粉尘进行吸附。相关标准的制定最早可以追溯到1960年代以前。注意&#xff0c;本文的附录包含一起完整的工业除尘器事故的分析和定责过程。相关事故分析定责文档源头摘自上海市政府网站。 在产品设计行业和关联下游行业&#xff0c;在…