文档首页 > > 开发指南> 内核开发指南> 队列> 概述

概述

分享
更新时间:2020/06/24 GMT+08:00

基本概念

队列又称消息队列,是一种常用于任务间通信的数据结构,实现了接收来自任务或中断的不固定长度的消息,并根据不同的接口选择传递消息是否存放在自己空间。任务能够从队列里面读取消息,当队列中的消息是空时,挂起读取任务;当队列中有新消息时,挂起的读取任务被唤醒并处理新消息。

用户在处理业务时,消息队列提供了异步处理机制,允许将一个消息放入队列,但并不立即处理它,同时队列还能起到缓冲消息作用。

Huawei LiteOS中使用队列数据结构实现任务异步通信工作,具有如下特性:

  • 消息以先进先出方式排队,支持异步读写工作方式。
  • 读队列和写队列都支持超时机制。
  • 发送消息类型由通信双方约定,可以允许不同长度(不超过队列节点最大值)消息。
  • 一个任务能够从任意一个消息队列接收和发送消息。
  • 多个任务能够从同一个消息队列接收和发送消息。
  • 当队列使用结束后,如果是动态申请的内存,需要通过释放内存函数回收。

运作机制

队列控制块

/**
  * @ingroup los_queue
  * Queue information block structure
  */
typedef struct tagQueueCB
{
    UINT8       *pucQueue;      /**< 队列指针 */
    UINT16      usQueueState;   /**< 队列状态 */
    UINT16      usQueueLen;     /**< 队列中消息个数 */
    UINT16      usQueueSize;    /**< 消息节点大小 */
    UNIT16      usQueueID;      /**< 队列ID号 */
    UINT16      usQueueHead;    /**< 消息头节点位置(数组下标)*/
    UINT16      usQueueTail;    /**< 消息尾节点位置(数组下标)*/
    UINT16      usReadWritableCnt[2];  /**< 队列中可写或可读消息数,0表示可读,1表示可写*/

    LOS_DL_LIST stReadWriteableList[2];    /**< 读写阻塞队列,0表示读阻塞队列,1表示写阻塞队列*/

    LOS_DL_LIST stMemList;      /**< MailBox模块使用 */
} QUEUE_CB_S;

每个队列控制块中都含有队列状态,表示该队列的使用情况:

  • OS_QUEUE_UNUSED:队列没有使用
  • OS_QUEUE_INUSED:队列被使用

队列运作原理

创建队列时,根据用户传入队列长度和消息节点大小来开辟相应的内存空间以供该队列使用,返回队列ID。

在队列控制块中维护一个消息头节点位置Head和一个消息尾节点位置Tail来表示当前队列中消息存储情况。Head表示队列中被占用消息的起始位置。Tail表示队列中被空闲消息的起始位置。刚创建时Head和Tail均指向队列起始位置。

写队列时,根据Tail找到被占用消息节点末尾的空闲节点作为数据写入对象。如果Tail已经指向队列尾则采用回卷方式。根据usWritableCnt判断队列是否可以写入,不能对已满(usWritableCnt为0)队列进行写队列操作。

读队列时,根据Head找到最先写入队列中的消息节点进行读取。如果Head已经指向队列尾则采用回卷方式。根据usReadableCnt判断队列是否有消息读取,对全部空闲(usReadableCnt为0)队列进行读队列操作会引起任务挂起。

删除队列时,根据传入的队列ID寻找到对应的队列,把队列状态置为未使用,释放原队列所占的空间,对应的队列控制头置为初始状态。

图1 队列读写数据操作示意图
分享:

    相关文档

    相关产品

文档是否有解决您的问题?

提交成功!

非常感谢您的反馈,我们会继续努力做到更好!

反馈提交失败,请稍后再试!

*必选

请至少选择或填写一项反馈信息

字符长度不能超过200

提交反馈 取消

如您有其它疑问,您也可以通过华为云社区问答频道来与我们联系探讨

智能客服提问云社区提问