OpenHarmony之进程通讯

在我的上一篇文章中,讲到了OpenHarmony中进程通讯的有关内容,在本篇将具体介绍进程间的异步通讯。

首先我们怀着问题读代码:“进程间是如何传递大数据的?”

  • 消息队列解决任务间大数据的传递。
  1. 消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。
  2. 消息队列提供了异步处理机制,允许将一个消息放入队列,但不立即处理。同时队列还有缓冲消息的作用。
  3. 队列用于任务间通信,可以实现消息的异步处理。同时消息的发送方和接收方不需要彼此联系,两者间是解耦的。(设计原则是解耦

  • 下面我将结合代码来分析它的几大特性:

首先来看一个基本的消息队列:



  1. #ifndef LOSCFG_BASE_IPC_QUEUE_LIMIT
  2. #define LOSCFG_BASE_IPC_QUEUE_LIMIT 1024 //队列个数
  3. #endif
  4. LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL;//消息队列池
  5. LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList;//空闲队列链表,管分配的,需要队列从这里申请
  6. typedef struct {
  7. UINT8 *queueHandle; /**< Pointer to a queue handle */ //指向队列句柄的指针
  8. UINT16 queueState; /**< Queue state */ //队列状态
  9. UINT16 queueLen; /**< Queue length */ //队列中消息总数的上限值,由创建时确定,不再改变
  10. UINT16 queueSize; /**< Node size */ //消息节点大小,由创建时确定,不再改变,即定义了每个消息长度的上限.
  11. UINT32 queueID; /**< queueID */ //队列ID
  12. UINT16 queueHead; /**< Node head */ //消息头节点位置(数组下标)
  13. UINT16 queueTail; /**< Node tail */ //消息尾节点位置(数组下标)
  14. UINT16 readWriteableCnt[OS_QUEUE_N_RW];
  15. //队列中可写或可读消息数,0表示可读,1表示可写
  16. LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */
  17. //挂的都是等待读/写消息的任务链表,0表示读消息的链表,1表示写消息的任务链表
  18. LOS_DL_LIST memList;
  19. } LosQueueCB;//读写队列分离

具有以下特性

  • [√]消息以先进先出的方式排队,支持异步读写。
  • [√]读队列和写队列都支持超时机制。
  • [√]每读取一条消息,就会将该消息节点设置为空闲。
  • [√]发送消息类型由通信双方约定,可以允许不同长度的消息。
  • [√]一个任务能够从任意一个消息队列接收和发送消息。
  • [√]多个任务能够从同一个消息队列接收和发送消息。
  • [√]创建队列时所需的队列空间,默认支持接口内系统自行动态申请内存的方式,同时也支持将用户分配的队列空间作为接口入参传入的方式。

建立过程依次是:初始化队列->创建队列->任务A调用写队列接口发送消息,任务B通过读队列接口接收消息。

下面将举例分析初始化队列的过程



  1. LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID)//消息队列模块初始化
  2. {
  3. LosQueueCB *queueNode = NULL;
  4. UINT32 index;
  5. UINT32 size;
  6. size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB);//支持1024个IPC队列
  7. /* system resident memory, don't free */
  8. g_allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0 size);//常驻内存
  9. if (g_allQueue == NULL) {
  10. return LOS_ERRNO_QUEUE_NO_MEMORY;
  11. }
  12. (VOID)memset_s(g_allQueue size 0 size);//清0
  13. LOS_ListInit(&g_freeQueueList);//初始化空闲链表
  14. for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) {//循环初始化每个消息队列
  15. queueNode = ((LosQueueCB *)g_allQueue) + index;//一个一个来
  16. queueNode->queueID = index;//队列的身份证
  17. LOS_ListTailInsert(&g_freeQueueList &queueNode->readWriteList[OS_QUEUE_WRITE]);//通过写节点挂到空闲队列链表上
  18. }//这里要注意是用 readWriteList 挂到 g_freeQueueList链上的,要通过 GET_QUEUE_LIST 来找到 LosQueueCB
  19. if (OsQueueDbgInitHook() != LOS_OK) {//调试队列使用的.
  20. return LOS_ERRNO_QUEUE_NO_MEMORY;
  21. }
  22. return LOS_OK;
  23. }

总结:消息队列解决任务间大数据的传递,以一种异步,解耦的方式实现任务通讯。


最后,文章和注解内容会存在不少错漏之处,以上即为本篇的所有内容,因学识与能力有限,如有不足之处,请多多包涵与指教!

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值