Android Binder开卷

一、IPC介绍

IPC全名为inter-Process Communication,含义为进程间通信,是指两个进程之间进行数据交换的过程。

1.1为什么需要使用IPC?

内核空间和用户空间

在操作系统中存在用户空间(User space)和内核空间(Kernel space)。

Liunx采用虚拟内存管理技术,每一个进程都都有各自独立的进程地址空间(以32位系统为例,空间为4G大小的线性虚拟空间),无法直接访问物理内存。这样避免了进程直接操作系统内核,保证系统安全,并且让用户程序可使用比实际物理内存更大的地址空间。

  • 4G进程地址被划分为两部分,内核空间和用户空间。用户空间从0到3G,内核空间从3G到4G;
  • 用户进程通常情况下只能访问用户空间的虚拟地址,不能访问内核空间虚拟地址。只有用户进程进行系统调用(代表用户进程在内核态执行任务)等情况可访问到内核空间;
  • 用户内核对应进程,所以当进程切换,用户空间也会跟着变化;
  • 内核空间是由内核负责映射,不会跟着进程变化;内核空间地址有自己对应的页表,用户进程有不同额页表。
  • 所有进程的内核空间都是共享的,属于所有进程,内核空间的数据是可以进程间共享的,而用户空间则不可以。

进程隔离

进程隔离指的是,一个进程不能直接操作或者访问另外一个进程,也就是进程A不可以直接访问B的数据。

系统调用

用户空间需要访问内核空间,就需要借助系统来实现。系统调用是用户空间访问内核空间的唯一方式,保证了所有的资源访问都是在内核的控制下进行的,避免了用户进程对系统资源的越权访问,提升了系统的安全性和稳定性。

进程A和进程B的用户空间可以通过如下系统函数和内核空间进行交互。

  • copy_from_user:将用户空间的数据拷贝到内核空间。
  • copy_to_user:将内核空间的数据拷贝到用户空间。

内存映射

由于应用程序不能直接操作设备设备硬件地址,所以操作系统提供了一种机制:内存映射,把设备地址映射到进程虚拟内存区。

内存映射全名为Memory Map,在Liunx中通过系统调用函数mmap来实现内存映射。将用户空间的一块内存区域映射到内核空阿金。映射关系建立后,用户对这块内存的区域的修改可以直接反应到内核空间,反之亦然。内存映射能减少数据拷贝次数,实现用户空间和内核空间的高效互动。

二、Liunx的IPC通信原理

内核程序在内核空间分配内存并开辟一块内核缓存区,发送进程通过copy_from_user函数将数据拷贝到内核空空间的缓冲区中。同样,接收进程在接收数据时再自己的用户空间开辟一块内存缓存区,然后内核程序调用copy_to_user() 函数将数据从内核缓存区拷贝到接收进程。这样数据发送进程和数据接收进程完成了一次数据传输,也就是一次进程间通信。

Linux的IPC通信原理有两个问题:

  1. 一次数据传递需要经历:用户空间 –> 内核缓存区 –> 用户空间,需要2次数据拷贝,这样效率不高。
  2. 接收数据的缓存区由数据接收进程提供,但是接收进程并不知道需要多大的空间来存放将要传递过来的数据,因此只能开辟尽可能大的内存空间或者先调用API接收消息头来获取消息体的大小,浪费了空间或者时间。

2.1 Liunx中的IPC机制种类

  1. 管道(pipe)是Liunx有Unix那里继承过来的进程间通信机制。原理是在内存中创建一个共享文件,从而使通信双方利用这个共享文件来传递信息。这个共享文件比较特殊,它不属于文件系统并且只存在于内存中。另外,管道采用的是半双工通信方式,数据只能在一个方向上流动。
    简单的模型如下所示。

2、信号

信号是软件层次上对中断机制的一种模拟,是一种异步通信方式,进程不必通过任何操作来等待信号的到达。信号可以在用户空间进程和内核之间直接交互,内核可以利用信号来通知用户空间的进程发生了哪些系统事件。信号不适用于信息交换,比较适用于进程中断控制。

3、信号量

信号量是一个计数器,用来控制多个进程对共享资源的访问。它常用来作为一种锁机制,防止某种进程正在访问共享资源时,其他进程也访问该资源。主要作为进程间以及同意进程内不同线程之间的同步手段。

4、消息队列

消息队列时消息的链表,具有特定的格式,存放在内存中并由消息队列标识符标识,并且允许一个或多个进程向它写入与读取消息。信息会复制两次,因此对于频繁或者信息量大的通信不宜使用消息队列。

5、共享内存

多个进程可以直接读写的一块内存空间,是针对其他通信机制运行效率太低而设计的。为了在多个进程间交换信息,内核专门留出了一块内存区,可以由需要访问的进程映射到自己大的私有地址空间。进程就可以直接读写这一块内存而不需要进行数据的拷贝,从而大大的提高效率。

6、套接字

套接字是更为基础的进程间通信机制,与其他方式不同的是,套接字可用于不同机器之间的进程间通信。

2、2Android中的IPC机制

Android系统是基于Linux内核的,在Liunx内核基础上又扩展出了一些IPC机制。Android系统除了支持套接字,还支持序列化、Messenger、AIDL、Bundle、文件共享、ContentProvider、Binder等。

1、序列化

序列化指的是Serializable/Parcelable,Serializable是java提供的一个序列化接口,是一个空接口,为对象提供标准的序列化和反序列化操作。Parcelable接口时Android中序列化方式。

2、Messenger

Messagner对象可以在不同进程中传递,在Message中加入我们想要传的数据就可以在进程间进行数据传递了。Messagner是一种轻量级的IPC方案并对AIDL进行了封装。

3、AIDL

AIDL全名为Android interface definition Language,即Android接口定义语言。Messenger是以串口的方式来处理客户端发来的信息,如果又大量的消息发到服务端,服务端仍然一个一个处理再响应客户端显然是不适合的。另外还有一点,Messenger用来进程间进行数据传递但是不能满足跨进程的方法调用,这个时候需要使用AIDL了。

4、Bundle
Bundle实现了Parcelable接口,所以它可以方便的在不同的进程间传输。Acitivity、Service、Receiver都是在Intent中通过Bundle来进行数据传递。

5、文件共享
两个进程通过读写同一个文件来进行数据共享,共享的文件可以是文本、XML、JOSN。文件共享适用于对数据同步要求不高的进程间通信。

6、ContentProvider
ContentProvider为存储和获取数据了提供统一的接口,它可以在不同的应用程序之间共享数据,本身就是适合进程间通信的。ContentProvider底层实现也是Binder,但是使用起来比AIDL要容易许多。系统中很多操作都采用了ContentProvider,例如通讯录,音视频等,这些操作本身就是跨进程进行通信。

参考文档:

Android Binder原理

Binder系列

深入理解Android卷1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值