更多内容请访问:与华为官方共建的鸿蒙技术社区https://ost.51cto.com前言LinusTorvalds,Linux的创始人,在2000-08-25发给linux-kernel邮件列表的一封电子邮件中提到:Talkischeap。给我看代码。不过,今天小编要的不仅仅是代码,还要说说OpenHarmony,虽然不是特别出彩的对象,但也不是宇宙流行的人工智能,也不是酷到极致的自动驾驶。它和编辑器一样平凡,默默支持着OpenHarmony的内部运行,辅助着内核。对象Task的大哥的正常运行。关键数据结构首先不得不提一下队列的关键数据结构LosQueueCB,好无聊,但是小编不得不硬着头皮解释一下,没有这个灵魂数据,是无法理解队列的作品:typedefstruct{UINT8*队列;/**<指向队列句柄的指针*/UINT16queueState;/**<队列状态*/UINT16queueLen;/**<队列长度*/UINT16queueSize;/**<节点大小*/UINT16queueID;/**queueLen=len;queueCB->queueSize=msgSize;queueCB->队列=队列;queueCB->queueState=OS_QUEUE_INUSED;queueCB->readWriteableCnt[OS_QUEUE_READ]=0;queueCB->queueHead=0;queueCB->queueTail=0;LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_READ]);LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_WRITE]);LOS_ListInit(&queueCB->memList);LOS_IntRestore(intSave);*queueID=queueCB->queueID;OsHookCall(LOS_HOOK_TYPE_QUEUE_CREATE,queueCB);它是支撑算法的灵魂。内核对象的队列控制结构LosQueueCB通过队列指针指向具体队列的内容。队列分配queueLen条消息,每条消息的大小为queueSize。同时将头指针和尾指针初始化为0。第二步:第一条消息进入队列。生产者通过队列传递信息。这个生产者可以是各种任务。队列生成后,任务就迫不及待地放置消息了。我应该选择FIFO还是FILO?任务大哥面临着艰难的选择,这次我们选择了先进先出。下图是FIFO插入第一个数据后的内存形式。作为一个开源系统,OpenHarmony在下面的代码中很好地体现了这个操作:UINT32消息数据大小;UINT16队列位置;errno_trc;/*获取队列位置*/switch(OS_QUEUE_OPERATE_GET(operateType)){caseOS_QUEUE_READ_HEAD:queuePosition=queueCB->queueHead;((queueCB->queueHead+1)==queueCB->queueLen)?(queueCB->queueHead=0):(queueCB->queueHead++);休息;案例OS_QUEUE_WRITE_HEAD:(queueCB->queueHead==0)?(queueCB->queueHead=(queueCB->queueLen-1)):(--queueCB->queueHead);queuePosition=queueCB->queueHead;休息;caseOS_QUEUE_WRITE_TAIL:queuePosition=queueCB->queueTail;((queueCB->queueTail+1)==queueCB->queueLen)?(queueCB->queueTail=0):(queueCB->queueTail++);休息;...}OsQueueBufferOperate是队列内存的核心操作函数,FIFO算法的本质是往队列尾部添加数据,代码抽象为一个OS_QUEUE_WRITE_TAIL操作。请注意,该队列是一个循环队列。插入数据后移动尾指针时要小心。在最后一个物理空间被使用后,需要将其移动到队列的头部。这就是传说中的循环队列。循环大法的读者有一个疑问:如何判断最后一个物理空间用完了?(queueCB->queueTail+1)==queueCB->queueLen)这段C语言的语句很好的解释了这道题,我这里也忍不住了不要夸C语言。有了C语言,就有了我喜欢的linux内核,还有我们的OpenHarmony。queueLen是队列物理空间的边界值。如果下一条消息已经指向了这个边界值,那么内核必须乖乖让它回到原来的位置,也就是queueCB->queueTail=0,否则就会出现大问题——内存越界,这个它也有可能飞机被毁,财产被毁。因为我们的OpenHarmony应用在各个领域,如果是在自动驾驶领域,后果会很严重。当然,聪明的程序员不会让这种情况发生。第三步:继续生产数据嗯,上面的操作一再重复,但是OpenHarmony忠实地实现了这个行为:代码小编就不一一细说了,可以来点音乐吗?哦不,是照片。第四步:生产数据结束。制作人制作了四条消息后,觉得够了,就偷懒了,不干了。2.FIFO算法的第一步:当然是队列中的第一条消息,因为我们是FIFO,先来的消息先拉出来射!如上图,我们回顾一下入队的步骤,知道每条消息在第一条消息被消费后:我们在生产消息的过程中已经提到了函数OsQueueBufferOperate,我们回顾一下关键代码:/*getthe队列位置*/switch(OS_QUEUE_OPERATE_GET(operateType)){caseOS_QUEUE_READ_HEAD:queuePosition=queueCB->queueHead;((queueCB->queueHead+1)==queueCB->queueLen)?(queueCB->queueHead=0):(queueCB->queueHead++);break;queueHead是我们的头指针,它的移动也面临和生产过程一样的问题,需要在最后一个物理空间用完后移动到队头。方法大同小异,懒得解释了。OS_QUEUE_READ_HEAD是dequeue的关键过程,解决queueHead头指针如何移动的问题。Step2:继续消费直接上图Step3:消费完最后一条消息也被我们kill掉了,所以head指针和tail指针移动到下图的位置。此时队列为空,工作完成,消费者分散。小结本文主要介绍OpenHarmony内核对象队列的FIFO算法。更多信息请访问:与华为官方共建的鸿蒙技术社区https://ost.51cto.com