当前位置: 首页 > 科技观察

从IPC到DistributedSoftBus的随笔

时间:2023-03-12 23:52:55 科技观察

在Linux系统中,客观的说,缺乏一个对开发者比较友好的进程间通信框架。提到Linux上的进程间通信,通常会想到管道(匿名的,有名的)、信号/信号量、共享内存、消息队列和套接字。这些都是低级技术。有没有方便开发者使用的技术或者框架?软件总线和分布式软总线可能是一个不错的选择。Linux进程间通信一瞥Linux环境下的通信机制有很多种,各种通信方式都有其适用的场合。Pipeline是Linux最早支持的UnixIPC机制之一,也是实现起来最简单的通信机制。但是,进程间通信只能以半双工方式进行。信号是众多以异步方式通信的通信机制中的唯一一种。信号通信传输的数据较少,侧重于控制进程根据不同的信号触发不同的行为。消息队列是内核开发的一组链表,以队列的形式接收和发送信息,适用于传输数据量较小的场合。与管道通信相比,消息队列的优点是可以为每条消息指定特定的消息类型。接收时不需要按队列顺序,可以根据自定义条件接收特定类型的消息。但是,在消息信息的发送进程-操作系统内核和内核接收进程之间进行复制需要额外的CPU时间。共享内存通信机制可以在进程间传输大量的数据,并且由于读写进程把共享内存块当作自己的进程,可以直接读写,所以传输速度是最快的。但是,由于多个进程必须以互斥的形式访问共享内存块,所以还需要信号量机制来配合。信号量机制通过信号量值的变化来控制多个进程对共享资源的互斥访问,或者协调多个进程并发执行的节奏,实际上并不在进程之间传输数据。基于Socket的进程间通信机制是所有网络操作系统必不可少的基本功能,大多数现代进程间通信框架都是基于Socket的。比较长的DCOP是从KDE2.0开始的,它包含了一个非常强大的组件,叫做“桌面通信协议”,简称DCOP。从开发人员的角度来看,使用DCOP可以很容易地将强大的脚本功能添加到应用程序中。从用户的角度来看,DCOP使控制KDE应用程序并以强大而有趣的方式组合它们变得容易。本质上,DCOP是一种运行在套接字上的轻量级进程间通信机制。它由一个服务器(即dcopserver,它会在KDE启动时自动启动)和任意数量的客户端(支持DCOP的应用程序)组成。DCOP客户段可以通过服务器相互发送消息,请求执行功能等。kdebindings包包含用于Java的Qt/KDE绑定。您可以在Java中使用Qt/KDE类,还可以包括C、Perl和Python的绑定。您还可以使用这些语言的DCOP。它还包括XParts,将非KDE应用程序嵌入为KPart。DCOP一般用于在Linux运行时动态管理软件配置框架。一般的Linux软件在运行时读取配置文件后,所有的参数都不能再进行调整,但是Dcop可以在软件启动后根据需要重新配置软件的参数。.无处不在的D-Bus现在,在Linux中广泛使用的D-Bus是什么?D-Bus是一个具有面向对象接口的协议框架,是应用程序用户相互发现和监控的守护进程。换句话说,这是一个进程间通信系统,由两个守护进程组成,一个是系统范围的,另一个是用户会话范围的,提供生命周期跟踪、服务激活和安全检查等高级功能。这样的守护进程可以启动服务来为其他程序提供某些功能。D-Bus可以看作是DCOP的升级版,比DCOP复杂,DCOP主要用于桌面应用程序之间的通信。但是D-bus并不是一个普遍适用的通信系统,这一点与Corba等有着明显的区别。在设计之初,采用D-Bus设计作为用户交互界面和系统服务的解耦和通信,以及系统服务之间的通信。对于D-Bus来说,由于对端发送的数据是不可信的,必须做复杂的验证,这使得它比直接使用sockets读写数据慢2.5倍,甚至比DCOP、Corba等通信机制还要慢。Corba是另一个由来已久的存在。20多年前,Corba比D-Bus更快地实现了Orbit。Corba和D-Bus都使用了两种机制的通信协议,但Corba更通用、更开放。但是D-Bus在很多地方都是硬编码的,所以D-Bus比Corba要简单的多。DCOM是Windows下的IPC系统,类似于Corba。由于老码友多年没有接触过windows平台的软件开发,不知道现在发展到什么程度了。面向嵌入式的ubusOpenWrt提供的ubus类似于Linux桌面系统的D-Bus,其目标是提供系统级的进程间通信功能。设计理念基本相同,但与D-Bus相比,减少了内存空间,更适合嵌入式Linux低内存、低CPU性能的特殊环境。ubus是OpenWrt的RPC工具,2011年左右加入OpenWrt。为了提供各种后台进程和应用程序之间的通信机制,ubus模块由3部分组成:ubusd守护进程。ubus接口库ubus命令行工具ubus模块的核心是ubusd守护进程,它在系统启动时运行,负责进程间的消息路由和传递。其他进程注册到ubusd进程来发送和接收消息。该接口是通过使用L文件socket和TLV收发消息来实现的。每个进程在指定的命名空间下注册自己的路径。每个路径可以提供多个具有各种参数的函数处理程序,函数处理程序可以在处理完成后返回消息。ubus提供的功能主要包括以下四个方面:提供注册对象和方法供其他实体调用。调用其他应用提供的注册对象的控制接口。注册以侦听特定对象上的事件。向特定对象发送事件消息。ubus主要用于两个进程之间的通信,可以与用户以JSON格式交换数据,而不管消息的实际传输格式是什么。ubus代码基于LGPL2.1发布,正式用于OpenWrt12.09版本。KDBUSkdbusforthekernelenvironment是内核中实现的D-Bus,可以传输大数据块甚至GB级别的消息流,可以实现零拷贝消息传输。在最坏的情况下,一条消息及其回复过程不超过2次副本、2次验证和2次上下文切换。完整的凭证信息(用户ID、进程ID、cgroup信息、权限等)随每条消息一起传递,并且所有消息都带有时间戳。kdbus在内核中作为字符设备使用,首先打开该设备,然后调用mmap()将一个消息传递区映射到自己的地址空间。消息在该区域组装后,交给内核进行传输。内核只是简单地将消息从一个进程映射的区域复制到另一个进程的区域。一般kdbus通过memfd机制实现零拷贝消息传递。memfd是一个带有文件描述符的内存区域,可以被“封存”,即拥有它的进程不能再改变它的内容。进程要传输消息,首先在memfd区构造消息,封存,然后交给kdbus传输。根据消息的大小,内核可以将相应的内存页映射到接收进程的地址空间,从而避免复制数据。如果消息比较小,内存映射的开销比较大,此时直接复制数据。消息还可以带有接收回复的时间限制(“方法调用窗口”)。因为在内核中,kdbus是随时可用的,不需要像D-Bus那样启动一个daemon进程。Linux安全模块可以直接链接到它,可以避免竞争条件,API也得到了简化。另外,kdbus信号广播机制使用Bloomfilters来选择接收者,也提高了广播的效率。遗憾的是,kdbus曾尝试融入主流发行版的内核,但似乎没有成功,前景有点难料。FDBUSfordistributedsystems提供分布式进程间通信机制,支持跨主机C/S通信,使用服务名代替物理地址作为寻址方式,通过各种服务和心跳重连机制保证动态连接和可靠性,从而保证:系统中的节点可以动态增删部署,可以任意重启,无需管理启动顺序和依赖关系,所有通信方都可以保持连接,从而形成一个个独立模块的坚实整体。从进程间通信的角度来看,FDBus类似于D-Bus,但功能更完备,性能更高,使用更方便。除了支持主机内的IPC外,还可以在多台主机之间形成网络。FDBus建立在socket(Unix和TCP)之上,使用protocolbuffer支持各种复杂的数据类型,也支持原始数据格式,便于海量数据传输。FDBus使用IDL定义接口,支持代码自动生成,大大减少了序列化和反序列化的工作。还支持安全策略,对访问区域进行安全等级划分,保证整个系统的安全。FDBus支持以字符串形式的名称作为服务器地址,通过类似DNS的名称服务器,自动为服务器分配一个Unix域地址和TCP端口号,使客户端和服务器可以通过服务寻址姓名。其高性能主要体现在点对点直接通信,无需通过中心Hub或Broker转发。它已在Windows、Linux和QNX上得到验证。作为C/S模式,它支持以下几种通信方式:同步请求超时/响应异步请求超时/响应无响应命令请求订阅模式,实现组播FDBus不仅是一种IPC机制,还是一个中间件开发框架,包括中间件开发过程中经常用到的通用组件和基础模型,提供跨平台强大的支持。FDBus源码开放后,经过更多开发者的使用、测试和改进,逐渐成为众多中间件开发框架的候选者之一。xBus与软件总线除了早期的DCOP,上面的进程间通信机制都命名为xBus,为什么呢?在计算机领域,Bus这个词最早出现在硬件架构中,代表总线,是一组可以被多个组件及时共享的公共信息传输线路。从总线的位置可分为片内总线和片外总线。片上总线是CPU内部寄存器、算术逻辑元件、控制元件和总线接口元件之间的公共信息通道。片外总线一般是指CPU与外部设备之间的公共信息通道。我们所说的总线一般指的是片外总线。从总线传输设计的角度来看,计算机总线包括串行总线和并行总线,可以由一个或多个通道组成。每个通道都是单线连接,数据传输方式会根据通道数的不同而有所不同。从通信用途来看,总线可分为地址总线、数据总线和控制总线三种。地址总线用于指定CPU要操作的内存地址;数据总线用于读写内存数据,控制总线用于发送和接收信号,如中断、设备复位等,CPU收到信号后做出响应,这时就需要控制总线。当CPU、内存和外设确定后,电脑的总线速度就是制约电脑整体性能的关键。计算机软件总线是一种虚拟的存在,它是在类比计算机硬件总线的功能和意义的基础上定义的。软件总线是软件工程师为进一步保证软件系统建设的规范化,提高计算机系统的应用价值而提出的一种设计理念。软件总线可以将各种软件相互连接起来,形成一个通用的操作平台,通常表示为接口。软件总线作为一个软件模块,为各个软件组件进行准确的数据传输,同时为各种软件提供虚拟的共享通道和接口。软件总线起源于分布式异构环境的构建,软件复用、组件化和面向对象技术的发展促进了它的形成。软件总线只对软件的组件进行组装,而不是对其进行改动,不仅有效地提高了软件开发的工作效率,而且缩短了软件开发的周期。上面提到的各种xBus,都可以看作是软件总线的一种实现。HarmonyOS的分布式软总线HarmonyOS的分布式软总线是为了解决所有1+8+N设备之间的互联互通问题。华为提出的1+8+N中:1指手机,8指汽车、音箱、耳机、手表/手环、平板、大屏、PC、AR/VR,N指其他IOT设备.通常,用户通过手动操作来连接设备。随着外围设备越来越多,手动操作不便,甚至会影响用户体验。HarmonyOS的分布式总线技术,是为了让所有设备之间能够便捷、高效的互联互通。HarmonyOS分布式软总线的主要功能包括:发现、连接、组网/拓扑管理、任务总线、数据总线。其中,“发现”是指搜索周围是否有相关设备;“连接”是指与发现的设备建立连接;“网络/拓扑管理”是指对所有发现的设备进行网络拓扑管理,例如形成星型网络拓扑,或者形成Mesh网络拓扑。“任务总线”是指基于已建立的网络拓扑结构,用于传输少量数据信息的路径。“数据总线”是指用来传输大量信息的通路。发现和联网是分布式软总线的核心技术,没有公开细节。连接很多外围设备组成网络后,需要保证各个设备的时间同步。尤其是物联网设备,由于成本原因,晶振的质量可能会比较差,会出现比较大的频率漂移。分布式软总线的关键技术之一是时钟同步算法,将原本不同步的不同设备的时钟进行同步。在软时钟算法的同步下,可以进行资源调度。LaneHub的概念是在软总线技术中提出的,可以理解为调度管理各个通信路径的模块。通过软总线的LaneHub,可以统一调度不同连接方式的设备,减少干扰,提高速度。在分布式软总线的基础上,华为提出了“超级终端”的概念,即通过分布式软总线技术将手机周围的其他相关设备连接起来,形成一个所谓的“超级终端”,即个人terminal变成成为一个组终端。一句话总结虽然“所有的程序都会归于系统调用”,但软件工程的效率提升是业界不变的追求,从进程间通信到分布式软总线。或许,基于FDBUS,开发类似HarmonyOS的分布式软总线还是比较容易的。【参考资料】https://gitee.com/Janisa/Dcop/http://dbus.freedesktop.org/doc/dbus-faq.htmlhttps://github.com/skawu/fdbushttps://git.openwrt。org/project/ubus.githttps://developer.harmonyos.com/https://www.bilibili.com/video/BV16b4y1h75z?spm_id_from=333.999.0.0