Binder 详解

什么是 Binder

Binder 是一种进程间通信机制,基于开源的 OpenBinder 实现;OpenBinder 起初由 Be Inc. 开发,后由 Plam Inc. 接手。从字面上来解释 Binder 有胶水、粘合剂的意思,顾名思义就是粘和不同的进程,使之实现通信。

Binder 的由来

我们知道,Android 系统就是运行在 Linux 系统之上。而 Linux 本身就具备一些跨进程通信的方式,比如:

1. 管道。性能损耗比较严重,一次通信需要 copy 两次数据
2. 共享内存。管理比较混乱,容易出错
3. socket。主要用于网络通信,有点杀鸡用牛刀。

出于 安全性稳定性性能的考虑,Android 系统提供了 Binder 进行 IPC 进程间通信

性能

Socket 作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中,然后再从内核缓存区拷贝到接收方缓存区,至少有两次拷贝过程。共享内存虽然无需拷贝,但控制复杂,难以使用。Binder 只需要一次数据拷贝,性能上仅次于共享内存。

稳定性

Binder 基于 C/S 架构,客户端(Client)有什么需求就丢给服务端(Server)去完成,架构清晰、职责明确又相互独立,自然稳定性更好。共享内存虽然无需拷贝,但是控制负责,难以使用。从稳定性的角度讲,Binder 机制是优于内存共享的。

安全性

Android 作为一个开放性的平台,市场上有各类海量的应用供用户选择安装,因此安全性对于 Android 平台而言极其重要。作为用户当然不希望我们下载的 APP 偷偷读取我的通信录,上传我的隐私数据,后台偷跑流量、消耗手机电量。
传统的 IPC 没有任何安全措施,完全依赖上层协议来确保。首先传统的 IPC 接收方无法获得对方可靠的进程用户ID/进程ID(UID/PID),从而无法鉴别对方身份。
Android 为每个安装好的 APP 分配了自己的 UID,故而进程的 UID 是鉴别进程身份的重要标志。传统的 IPC 只能由用户在数据包中填入 UID/PID,但这样不可靠,容易被恶意程序利用。可靠的身份标识只有由 IPC 机制在内核中添加。其次传统的 IPC 访问接入点是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。
同时 Binder 既支持实名 Binder,又支持匿名 Binder,安全性高。

Binder 优势总结

  • 性能:只需要 copy 一次数据,仅次于内存共享
  • 稳定性:基于 C/S 架构,架构清晰、职责明确又相互独立
  • 安全性:为每个 APP 都分配一个 UID,用于进程的身份识别

Binder 通信机制

首先从宏观上看一下 Binder 是怎么完成一次数据的跨进程传输的。

在这里插入图片描述

再来从微观上看一下数据是怎么进行传递的

在这里插入图片描述

上面两个图中涉及到了 Linux 中跨进程通信的一些概念

  1. 进程隔离
  2. 进程空间划分:用户空间(User Space)/内核空间(Kernel Space)
  3. 系统调用:用户态/内核态

进程隔离

简单的说就是操作系统中,进程与进程间内存是不共享的。两个进程就像两个平行的世界,A 进程没法直接访问 B 进程的数据,这就是进程隔离的通俗解释。A 进程和 B 进程之间要进行数据交互就得采用特殊的通信机制:进程间通信(IPC)。

进程空间划分:用户空间(User Space)/内核空间(Kernel Space)

内核空间(Kernel)是系统内核运行的空间,用户空间(User Space)是用户程序运行的空间。为了保证安全性,它们之间是隔离的。

系统调用:用户态与内核态

虽然从逻辑上进行了用户空间和内核空间的划分,但不可避免的用户空间需要访问内核资源,比如文件操作、访问网络等等。为了突破隔离限制,就需要借助系统调用来实现。系统调用是用户空间访问内核空间的唯一方式,保证了所有的资源访问都是在内核的控制下进行的,避免了用户程序对系统资源的越权访问,提升了系统安全性和稳定性。

Binder 四个重要角色

基本概念性东西都已经介绍完了,主要在于那两张图。图中一共涉及四个重要角色 ServerClientServiceManagerBinder驱动

在这里插入图片描述

上面说到 Binder 是基于 B/S 架构设计,Client、Server、Service Manager 运行在用户空间,Binder 驱动运行在内核空间。其中 Service Manager 和 Binder 驱动由系统提供,而 Client、Server 由应用程序来实现。
Client、Server 和 ServiceManager 均是通过系统调用 open、mmap 和 ioctl 来访问设备文件 /dev/binder,从而实现与 Binder 驱动的交互来间接的实现跨进程通信。

这里用一张图来总结一下

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章