OpenHarmony开源社区
直播中

张宇

7年用户 1669经验值
私信 关注
[经验]

OpenHarmony进程间是如何传递大数据的

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

消息队列解决任务间大数据的传递。

消息队列,是一种常用于任务间通信的数据结构。队列接收来自任务或中断的不固定长度消息,并根据不同的接口确定传递的消息是否存放在队列空间中。

消息队列提供了异步处理机制,允许将一个消息放入队列,但不立即处理。同时队列还有缓冲消息的作用。

队列用于任务间通信,可以实现消息的异步处理。同时消息的发送方和接收方不需要彼此联系,两者间是解耦的。(设计原则是解耦)

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

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

#ifndef LOSCFG_BASE_IPC_QUEUE_LIMIT

#define LOSCFG_BASE_IPC_QUEUE_LIMIT 1024 //队列个数

#endif

LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL;//消息队列池

LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList;//空闲队列链表,管分配的,需要队列从这里申请

typedef struct {

UINT8 *queueHandle; /**< Pointer to a queue handle */ //指向队列句柄的指针

UINT16 queueState; /**< Queue state */ //队列状态

UINT16 queueLen; /**< Queue length */ //队列中消息总数的上限值,由创建时确定,不再改变

UINT16 queueSize; /**< Node size */ //消息节点大小,由创建时确定,不再改变,即定义了每个消息长度的上限.

UINT32 queueID; /**< queueID */ //队列ID

UINT16 queueHead; /**< Node head */ //消息头节点位置(数组下标)

UINT16 queueTail; /**< Node tail */ //消息尾节点位置(数组下标)

UINT16 readWriteableCnt[OS_QUEUE_N_RW];

//队列中可写或可读消息数,0表示可读,1表示可写

LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */

//挂的都是等待读/写消息的任务链表,0表示读消息的链表,1表示写消息的任务链表

LOS_DL_LIST memList;

} LosQueueCB;//读写队列分离

具有以下特性

[√]消息以先进先出的方式排队,支持异步读写。

[√]读队列和写队列都支持超时机制。

[√]每读取一条消息,就会将该消息节点设置为空闲。

[√]发送消息类型由通信双方约定,可以允许不同长度的消息。

[√]一个任务能够从任意一个消息队列接收和发送消息。

[√]多个任务能够从同一个消息队列接收和发送消息。

[√]创建队列时所需的队列空间,默认支持接口内系统自行动态申请内存的方式,同时也支持将用户分配的队列空间作为接口入参传入的方式。

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

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

LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID)//消息队列模块初始化

{

LosQueueCB *queueNode = NULL;

UINT32 index;

UINT32 size;

size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB);//支持1024个IPC队列

/* system resident memory, don't free */

g_allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0, size);//常驻内存

if (g_allQueue == NULL) {

return LOS_ERRNO_QUEUE_NO_MEMORY;

}

(VOID)memset_s(g_allQueue, size, 0, size);//清0

LOS_ListInit(&g_freeQueueList);//初始化空闲链表

for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) {//循环初始化每个消息队列

queueNode = ((LosQueueCB *)g_allQueue) + index;//一个一个来

queueNode->queueID = index;//队列的身份证

LOS_ListTailInsert(&g_freeQueueList, &queueNode->readWriteList[OS_QUEUE_WRITE]);//通过写节点挂到空闲队列链表上

}//这里要注意是用 readWriteList 挂到 g_freeQueueList链上的,要通过 GET_QUEUE_LIST 来找到 LosQueueCB

if (OsQueueDbgInitHook() != LOS_OK) {//调试队列使用的.

return LOS_ERRNO_QUEUE_NO_MEMORY;

}

return LOS_OK;

}

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

原作者:夏贤凤

更多回帖

发帖
×
20
完善资料,
赚取积分