Android系统IPC机制

发布时间:2023年12月19日

Android系统IPC机制

介绍

在安卓系统上,我们知道每个应用都在自己的进程中运行。当应用加载时,应用程序管理器通知Zygote。Zygote分叉自身并复制虚拟机(VM)。因此,应用程序获得一个具有加载库的“热”VM。每个安卓应用都是沙盒化的,因此每个进程相互独立。沙盒概念用于管理或包含不同级别的权限,限制在每个个体应用中。因此,它需要IPC来在应用/服务/系统服务之间进行通信。在一个进程下,可能有多个线程,它们共享进程内存,但有自己的堆栈。

IPC是任何软件系统/操作系统的基础。安卓提供了两种实现IPC的方式。

  1. ashmem
  2. Binder
  3. Socket

上述三种方式支持设备内的IPC。让我们首先了解一下ashmem。

ashmem

ashmem(匿名共享内存子系统)类似于POSIX SHM(共享内存)的概念。不同之处在于,ashmem声称克服了内存泄漏的问题。ashmem不适用于安卓应用,而是被低级别的系统软件/进程使用。系统服务器的组件,如SurfaceFlinger、AudioFlinger等,使用ashmem进行IPC。ashmem速度很快。另一个使用ashmem的例子是虚拟机,它使用ashmem提供的.oat代码。当一个进程想要与另一个进程通信时,该进程创建一个共享内存区域,然后通过Binder将该内存区域的文件描述符与它要通信的其他进程共享。这个文件描述符通过Binder发送给另一个进程。系统进程通过IMemory接口依赖ashmem,这对应用程序开发者不可见或不公开。

ashmem还进行内存管理,根据需要收缩或扩展内存区域。当系统需要更多内存时,它会缩小其区域并释放内存。如果将共享内存区域标记为固定,那么在任何情况下都不能释放该区域。ashmem使用引用计数销毁与其关联的内存区域,当引用它们的进程退出时。

基本上,ashmem是由系统级别进程使用的一种IPC方式,而不是应用程序进程。

Binder

Binder的历史

Binder框架有着悠久的历史。最初是为Be计算机开发的,后来被Palm接管并嵌入到Palm OS中。在2005年,Binder框架以OpenBinder的名义开源(参考:OpenBinder)。Binder框架的幕后人物是由Dianne Hackborn领导的团队。在Binder领域中另一个著名的名字是George Hoffman。后来,Google聘请了这个团队来重新设计Binder框架,重新开发了Binder框架,自那时以来它就成为了安卓的一部分。

Binder的位置

谈到Binder时,要注意你的受众是谁。通过“Binder”这个词,应用程序开发者可能会想象在框架中可用的Binder接口,以绑定到应用程序服务。另一方面,Binder的强度远不止于应用程序开发者可见的框架级别的Binder接口(IBinder)。对于应用程序开发者,有一些IPC技术可用,如Messenger、Intent、AIDL和IBinder接口本身。然而,在背后,所有这些都是基于Binder的。AOSP显示,每个都使用IBinder接口。在这里,通过“Binder”,我指的是安卓中的整个“Binder框架”。那么,我所指的这个Binder在哪里呢?

是的,Binder无处不在。上图显示了安卓系统的简要表示。有Linux内核、库、ART、框架和应用程序。每个块中都显示了一些示例内容(带箭头)。每个块中显示的蓝色框都是Binder框架的组件。Binder框架的一部分坐落在被称为Binder Driver的内核中。还有Libbinder.so,它是安卓库的一部分的Binder库。然后,在安卓框架中有IBinder接口。应用程序开发者实例化此接口以在应用程序级别进行IPC。因此,技术上,Binder贯穿整个系统栈。

在Linux系统中,有几种IPC机制可用,如文件、信号、套接字、管道,以及更高级别的D-Bus。与Android一起使用的Linux内核不包含这些强大的机制。相反,Binder替换了它们。

Binder的构建块

Binder的构建块不是确切的构建块,而是Binder的重要概念或抽象思想:

  1. Binder上下文管理器
  2. Binder服务和客户端
  3. Binder令牌
  4. Binder协议
  5. Binder驱动程序
Binder上下文管理器

当系统启动时,Binder驱动程序允许一个进程将自身注册为上下文管理器。该进程是安卓系统的服务管理器。正如我们所知,服务管理器是所有系统服务的中央注册表。

Binder服务和客户端

要在两个进程之间

进行通信,应该有两个进程。一个是服务,另一个订阅它的将被称为客户端。

Binder令牌

Binder令牌用于标识。当将Binder消息传递给其他进程时,它会携带一个标识令牌,以识别发送者。

Binder协议

Binder协议只是在从一个进程传递消息到另一个进程时发生的不同步骤。消息传递不能像下面这样进行:

而应该考虑以下图示:

在上图中,有两个进程A和B,A想向B发送消息(黄色框)。这两个进程应该通过IBinder接口(Intent、AIDL、IBinder、Messenger,都无关紧要)相互“绑定”。每个进程上显示的绿色椭圆是只读内存区域,从中各自的进程可以读取数据,但不能写入。只有内核可以将数据写入这些绿色椭圆。与任何其他设备驱动程序一样,Binder驱动程序还实现了ioctl()函数。进程A调用此函数将消息传递给Binder驱动程序。Binder驱动程序提供了一个名为binder_write_read的特殊结构。消息以此格式传递。

如上图所示,现在数据已经传输到内核空间。从这里,内核将数据放入通信通道的另一侧,最终进入B进程的内存区域,如下图所示:

从这里,进程B读取它以进行进一步处理。

Binder驱动程序

如上所述,binder驱动程序是一个软件组件,加载在内核空间中,负责将数据从一个进程的内存区域传递到另一个进程。可以通过ioctl()调用访问它。

注意:只读内存区域在进程区域中显示。但它们实际上是由内核管理的。

Binder特性

Binder支持:

  1. 双向通信
  2. 管理:线程、内存、对象映射、引用计数
  3. 通知:当服务终止时,Binder负责通知客户端有关服务终止的情况
  4. 标识和安全性:使用Binder令牌进行标识;还基于UID和PID
  5. 事务数据(包裹)的编组
  6. 在进程之间共享ashmem内存区域的文件描述符
  7. 本地执行模式:如果通信在一个进程内进行,则不经过内核,而是使用本地共享内存

Socket

也许会让人惊讶,但安卓使用套接字与系统的某个组件通信。那就是Zygote。当Zygote被冷启动(通过从init.rc启动的app_process启动)时,它启动一个VM并保持一个套接字打开以侦听来自应用程序管理器的指令。当用户启动应用程序时,应用程序管理器通过此打开的套接字通知Zygote。

文章来源:https://blog.csdn.net/u011897062/article/details/135092332
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。