0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

鸿蒙内核进程间为何要通讯?

鸿蒙系统HarmonyOS 来源:my.oschina 作者: 鸿蒙内核源码分析 2021-04-24 11:28 次阅读

进程间为何要通讯 ?

鸿蒙内核默认支持 64个进程和128个任务,由进程池和任务池统一管理.内核设计尽量不去打扰它们,让各自过好各自的日子, 但大家毕竟在一口锅里吃饭, 不可能不与外界联系, 联系就得有渠道,有规矩.

举两个应用场景说明下通讯的必要性:

一.被动式广为熟知的shell命令 kill 9 13 ,是通过 shell任务给 13号进程发送一个干掉它的信号.

#define SIGKILL   9		//常用的命令 kill 9 13 

这是被动式通讯的场景,至于为什么要干掉你,原因可能很多啊,很可能是检测到13占用内存太多了,也可能13太低调长期不活跃,启动新进程发现没位置了,得先收了你.总之系统必须得有对付你的抓手,可以随时登门查水电表.

二.主动式的,比如要访问某些公共资源(全局变量,消息队列),而资源有限或具有排他性,别人正在使用导致你不能用, 所以需统一管理,要用就必须要先申请,按规矩办事,毕竟和谐社会没规矩不成方圆.如果申请失败了就需要排队了,同时还要让出CPU给别人占用了,否则占着茅坑不办事这样对大家都不好撒.

大致有以下几种通讯需求:

(1).数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到KB字节之间.(liteipc消息队列默认1K)

(2).共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到。

(3).通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)。

(4).资源共享:多个进程之间共享同样的资源。为了做到这一点,需要内核提供锁和同步机制。

(5).进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变。

内核目录和系列篇更新

内核有个专门的IPC目录,详见如下. 可直接点击查看注解源码.

pIYBAGCDj82AJApcAAC3HJ8TzdA474.png

进程间九种通讯方式

1.管道pipe(fs_syscall.c)

管道是一种最基本的IPC机制,作用于有血缘关系的进程之间,完成数据传递。 调用pipe系统函数即可创建一个管道。有如下特质:

其本质是一个伪文件(实为内核缓冲区)

由两个文件描述符引用,一个表示读端,一个表示写端。

规定数据从管道的写端流入管道,从读端流出。

管道的原理: 管道实为内核使用环形队列机制,借助内核缓冲区(4k)实现。 管道的局限性: ① 数据自己读不能自己写。 ② 数据一旦被读走,便不在管道中存在,不可反复读取。 ③ 由于管道采用半双工通信方式。因此,数据只能在一个方向上流动。 ④ 只能在有公共祖先的进程间使用管道。 常见的通信方式有,单工通信、半双工通信、全双工通信。

这部分后系列篇文件相关篇中会重点讲,敬请关注. 详细看SysPipe函数.

2.信号(los_signal.c)

信号思想来自Unix,在发展了50年之后,许多方面都没有发生太大的变化.信号可以由内核产生,也可以由用户进程产生,并由内核传送给特定的进程或线程(组),若这个进程注册/安装了自己的信号处理程序,则内核会调用这个函数去处理信号,否则则执行默认的函数或者忽略.信号分为两大类:可靠信号与不可靠信号,前32种信号为不可靠信号,后32种为可靠信号。长这样:

#define SIGHUP    1	//终端挂起或者控制进程终止
#define SIGINT    2	//键盘中断(如break键被按下)
#define SIGQUIT   3	//键盘的退出键被按下
#define SIGILL    4	//非法指令
#define SIGTRAP   5	//跟踪陷阱(trace trap),启动进程,跟踪代码的执行
#define SIGABRT   6	//由abort(3)发出的退出指令
#define SIGIOT    SIGABRT 
#define SIGBUS    7	//总线错误 
#define SIGFPE    8	//浮点异常
#define SIGKILL   9		//常用的命令 kill 9 13 
#define SIGUSR1   10	//用户自定义信号1 

信号为系统提供了一种进程间异步通讯的方式,一个进程不必通过任何操作来等待信号的到达。事实上,进程也不可能知道信号到底什么时候到达。一般来说,只需用户进程提供信号处理函数,内核会想方设法调用信号处理函数,处理过程如图所示:

o4YBAGCDj-CAdh-kAAFsows6BkA259.png

个人把这种异步通讯过程理解为生产者(安装和发送信号)和消费者(捕捉和处理信号)两个部分,分姊妹两篇已完成

v48.xx (信号生产篇) | 如何安装和发送信号?< csdn | 51cto | harmony >

v49.xx (信号消费篇) | 用户栈到内核栈的两次切换< csdn | 51cto | harmony >

3.消息队列(los_queue.c)

基本概念

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

任务能够从队列里面读取消息,当队列中的消息为空时,挂起读取任务;当队列中有新消息时, 挂起的读取任务被唤醒并处理新消息。任务也能够往队列里写入消息,当队列已经写满消息时, 挂起写入任务;当队列中有空闲消息节点时,挂起的写入任务被唤醒并写入消息。如果将 读队列和写队列的超时时间设置为0,则不会挂起任务,接口会直接返回,这就是非阻塞模式。

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

队列特性

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

详细可前往查看:

v33.xx (消息队列篇) | 进程间如何异步解耦传递大数据 ?< csdn | 51cto | harmony >

4.共享内存(shm.c)

共享内存是进程间通信中最简单的方式之一。共享内存允许两个或更多进程访问同一块物理内存,每个进程都要单独对这块物理内存进行映射.当一个进程改变了这块地址中的内容的时候,该物理页框将被标记为脏页,如此其它进程都会知道内容发生了更改。

这部分后系列篇内存相关篇中会重点讲,内存部分虽已写过几篇,但是没讲透,要重新再梳理.

5.信号量(los_sem.c)

基本概念

信号量(Semaphore)是一种实现任务间通信的机制,可以实现任务间同步或共享资源的互斥访问。 一个信号量的数据结构中,通常有一个计数值,用于对有效资源数的计数,表示剩下的可被使用的共享资源数。

对信号量有个形象的比喻 停车场的停车位, 进停车场前看下屏幕上实时显示剩余车位,0表示不能进,只有大于0才能进入,进入后自动减1,出口处也加了监测,出去后剩余车位增加1个.

使用场景

在多任务系统中,信号量是一种非常灵活的同步方式,可以运用在多种场合中,实现锁、同步、资源计数等功能, 也能方便的用于任务与任务,中断与任务的同步中。常用于协助一组相互竞争的任务访问共享资源。

详细可前往查看:

v29.xx (信号量篇) | 信号量解决任务同步问题< csdn | 51cto | harmony >

6.互斥锁 (los_mux.c) :

基本概念

互斥锁又称互斥型信号量,是一种特殊的二值性信号量,用于实现对临界资源的独占式处理。 另外,互斥锁可以解决信号量存在的优先级翻转问题。 任意时刻互斥锁只有两种状态,开锁或闭锁。当任务持有时,这个任务获得该互斥锁的所有权, 互斥锁处于闭锁状态。当该任务释放锁后,任务失去该互斥锁的所有权,互斥锁处于开锁状态。 当一个任务持有互斥锁时,其他任务不能再对该互斥锁进行开锁或持有。

详细可前往查看:

v27.xx (互斥锁篇) | 互斥锁比自旋锁可丰满许多< csdn | 51cto | harmony >

v26.xx (自旋锁篇) | 真的好想为自旋锁立贞节牌坊!< csdn | 51cto | harmony >

7.快锁 (los_futex.c)

futex 是Fast Userspace muTexes的缩写(快速用户空间互斥体),是一种用户态和内核态混合的同步机制。首先,同步的进程间通过mmap共享一段内存,futex变量就位于这段共享的内存中且操作是原子的,当进程尝试进入互斥区或者退出互斥区的时候,先去查看共享内存中的futex变量,如果没有竞争发生,则只修改futex,而不用再执行系统调用了。当通过访问futex变量告诉进程有竞争发生,则还是得执行系统调用去完成相应的处理(wait 或者 wake up)。

注解版同步到官方最新源码后,发现快锁的部分改动很大,这部分要重新注解,敬请留意.

8.事件 (los_event.c)

基本概念事件(Event)是一种任务间通信的机制,可用于任务间的同步。

多任务环境下,任务之间往往需要同步操作,一个等待即是一个同步。事件可以提供一对多、多对多的同步操作。 一对多同步模型:一个任务等待多个事件的触发。可以是任意一个事件发生时唤醒任务处理事件,也可以是几个事件都发生后才唤醒任务处理事件。 多对多同步模型:多个任务等待多个事件的触发。

事件特点

任务通过创建事件控制块来触发事件或等待事件。 事件间相互独立,内部实现为一个32位无符号整型,每一位标识一种事件类型。第25位不可用,因此最多可支持31种事件类型。 事件仅用于任务间的同步,不提供数据传输功能。 多次向事件控制块写入同一事件类型,在被清零前等效于只写入一次。 多个任务可以对同一事件进行读写操作。 支持事件读写超时机制。

事件可应用于多种任务同步场景,在某些同步场景下可替代信号量。

使用场景

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

详细可前往查看:

v30.xx (事件控制篇) | 任务间多对多的同步方案< csdn | 51cto | harmony >

9.文件消息队列 (hm_liteipc.c)

基于文件实现的消息队列,特点是队列中消息数量多(256个),传递消息内容大(可到1K)

#define IPC_MSG_DATA_SZ_MAX 1024	//最大的消息内容 1K ,posix最大消息内容 64个字节
#define IPC_MSG_OBJECT_NUM_MAX 256	//最大的消息数量256 ,posix最大消息数量 16个

文件消息队列隐约感觉鸿蒙的分布式通讯,跨屏之类的功能是靠它实现的,分布式的代码还没研究,尚不清楚,如果有了解的请告知.后续要重点研究下跨应用通讯的技术实现.

编辑:hfy

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 进程
    +关注

    关注

    0

    文章

    193

    浏览量

    13876
  • 鸿蒙系统
    +关注

    关注

    183

    文章

    2618

    浏览量

    65272
收藏 人收藏

    评论

    相关推荐

    鸿蒙内核源码Task/线程技术分析

    、使用内存空间等系统资源,并独立于其它线程运行。 鸿蒙内核每个进程内的线程独立运行、独立调度,当前进程内线程的调度不受其它进程内线程的影响。
    的头像 发表于 10-18 10:42 1950次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b>源码Task/线程技术分析

    【HarmonyOS】鸿蒙内核源码分析(调度机制篇)

    的?请读懂内核最美函数 OsGetTopTask()为什么学一个东西学那么多的概念?鸿蒙内核中 Task 和 线程 在广义上可以理解为是一个东西,但狭义上肯定会有区别,区别在于管理
    发表于 10-14 14:00

    鸿蒙源码分析系列(总目录) | 给HarmonyOS源码逐行加上中文注释

    内核源码分析(时钟管理篇) | 触发调度最大的源动力|-鸿蒙内核源码分析(进程管理篇) | 进程内核
    发表于 11-20 11:24

    鸿蒙内核源码分析(调度机制篇):Task是如何被调度执行的

    本文分析任务调度机制源码 详见:代码库建议先阅读阅读之前建议先读本系列其他文章,进入鸿蒙系统源码分析(总目录),以便对本文任务调度机制的理解。为什么学一个东西学那么多的概念?鸿蒙内核
    发表于 11-23 10:53

    鸿蒙内核源码分析(调度队列篇):进程和Task的就绪队列对调度的作用

    为何单独讲调度队列?鸿蒙内核代码中有两个源文件是关于队列的,一个是用于调度的队列,另一个是用于线程通讯的IPC队列。 本文详细讲述调度队列
    发表于 11-23 11:09

    鸿蒙内核源码分析(进程管理篇):进程内核的资源管理单元

    ProcessGroup *g_processGroup = NULL;// 进程组以上是进程模块全局变量。注释是笔者添加的,鸿蒙内核的注释很少,查看更多注释前往以下仓库
    发表于 11-24 11:23

    HarmonyOS 内核源码分析(下)—电子书上线啦!

    任务会因拥有锁而被迫改变优先级第十一章 进程的九种通讯方式第十二章 信号量解决任务同步问题第十三章 任务一对多和多对多的同步方案第十四章 内核
    发表于 04-01 17:33

    为何将Linux操作系统划分为用户和内核

    linux_C网络编程概述嵌入式网络编程==嵌入式Linux_C系统编程(文件、进程进程通信、多线程、网络、大并发网络服务器、数据库、shell编程)1、嵌入式C开发 VS 嵌入式Linux_C
    发表于 12-15 08:35

    鸿蒙内核实现用户态快速互斥锁Futex设计资料合集

    篇的末尾被提出来。鸿蒙内核进程池默认上限是 64 个,除去两个内核进程外,剩下的都归属用户进程
    发表于 03-23 14:12

    鸿蒙内核源码分析(百篇博客分析.挖透鸿蒙内核)

    入研究实在是暴殄天物,于心不忍。坚信鸿蒙大势所趋,未来可期,其必定成功,也必然成功,誓做其坚定的追随者和传播者。为何精读内核源码?每位码农的学职生涯,都应精读一遍
    发表于 07-04 17:16

    为何要精读鸿蒙内核源码?

    一个没学过计算机知识的卖菜大妈就不可能知道内核的基本运作了吗? 不一定!在系列篇中试图用 鸿蒙内核源码分析(总目录)之故事篇 去引导这一层级的认知,希望能卷入更多的人来关注基础软件,尤其是那些资本大鳄,加大对基础软件的投入。
    的头像 发表于 04-26 15:00 1459次阅读
    <b class='flag-5'>为何</b>要精读<b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b>源码?

    鸿蒙内核源码:进程内核的资源管理单元

    OpenHarmony内核进程模块可以给用户提供多个进程,实现了进程之间的切换和通信,帮助用户管理业务程序流程。
    的头像 发表于 04-24 10:58 1288次阅读
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b>源码:<b class='flag-5'>进程</b>是<b class='flag-5'>内核</b>的资源管理单元

    鸿蒙内核源码分析:task是内核调度的单元

    从系统的角度看,线程是竞争系统资源的最小运行单元。线程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它线程运行。 鸿蒙内核每个进程内的线程独立运行、独立调度,当前进程内线程
    发表于 11-23 15:51 22次下载
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b>源码分析:task是<b class='flag-5'>内核</b>调度的单元

    鸿蒙内核源码分析:进程和Task的就绪队列对调度的作用

    鸿蒙内核代码中有两个源文件是关于队列的,一个是用于调度的队列,另一个是用于线程间通讯的IPC队列。 鸿蒙内核
    发表于 11-23 15:48 31次下载
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b>源码分析:<b class='flag-5'>进程</b>和Task的就绪队列对调度的作用

    鸿蒙内核源码分析:进程内核的资源管理单元

    从系统的角度看,进程是资源管理单元。进程可以使用或等待CPU、使用内存空间等系统资源,并独立于其它进程运行。OpenHarmony内核进程
    发表于 11-24 17:52 22次下载
    <b class='flag-5'>鸿蒙</b><b class='flag-5'>内核</b>源码分析:<b class='flag-5'>进程</b>是<b class='flag-5'>内核</b>的资源管理单元