Binder纯理论分析

今天的主要是来对Binder做一个较全面的介绍,为之后的深入分析做一个预热准备。

Linux IPC

首先BinderAndroid中的一种独有的跨进程通信方式,简称IPC。它是专门为Android平台设计的。

那为什么要设计出Binder这个烦人的东西呢?我们都知道Android是基于Linux系统进行演变过来的,所以理应也能直接使用LinuxIPC通信方式。

所以在理解Binder的设计初衷之前,我们先来了解一下Linux系统中现有的IPC通信方式。

Linux现有的IPC通信方式有6种:

  1. 管道
  2. 信号量
  3. 信号
  4. 共享内存
  5. 消息队列
  6. socket
管道

英文为pipe,在Linux中它的本质是一个文件系统,通过一个进程以写的方式打开文件,另一个进程以读的方式进行打开文件,通过这样读写的方式,实现了进程间的通信。

只不过该文件是位于Linux内存中,所以操作管道就是以文件的方式操作Linux内存缓存区。

由于管道是通过读写文件的方式进行运作的,所以它需要进行两次数据的拷贝;分别是copy_form_user从写进程拷贝到文件内存缓存区,再通过copy_to_user从文件缓存区拷贝到读进程中。

同时管道还有大小限制,默认为4k,一旦写入端超过大小限制,管道将会阻塞。

信号量

主要作用于进程间的资源互斥访问,通过PV两种操作等待与发送信号。

P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行 V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.

所以信号量主要是用来解决多个进程对同一资源的竞争问题,类似于多线程的同步锁。

信号

Linux中定义的一种软中断,有64种,分为可靠信号与不可靠信号,多用于消息传递与通知,不适合传递信息。

共享内存

共享内存顾名思义,允许不同的进程访问同一块内存地址空间,它也需要进行两次数据拷贝操作,分别是将数据拷贝到共享内存中,又从共享内存中间将数据拷贝出来。

但需要注意的是,共享内存是不提供同步机制。

意思就是说,在其中一个进程进行写操作时,并不能放在另一进程进行读操作。

为了解决这个问题,共享内存一般都与前面说的信号量一起使用。

消息队列

消息队列通过一个进程向另一个进程发生消息块的方式进行通信,它与管道非常类似,都需要发送与接收,数据拷贝两次。

不同点是

  1. 消息队列可以防止同步与阻塞问题。
  2. 消息队列的接收方可以进行选择性接收。
  3. 发送的消息块有最大限制
socket

Linux中的socket是基于C/S架构的,传输效率低,多用于跨网络与跨设备的通信。

Android底层使用socket来进行initzygote等进程间的通信。

最后简单的来看一张图来了解在Linux中不同进程中的通信过程。

img

所以通过上面的分析,Linux现有的几种IPC通信方式都不是很适合Android间的进程通信。

例如管道、共享内存与消息队列都需要拷贝两次数据,同时有的还会存在阻塞与同步问题;另外的信号、信号量与socket由于使用场景的原因,都不适合用于Android中快速的进程间的数据通信。

Binder

那么Binder通信方式是怎么样的呢?

Binder本身是基于C/S架构的,层次分明,架构稳定,同时Binder内部只需使用一次数据拷贝操作,就能达到进程间数据的通信;另外Binder还支持鉴别用户进程的Uid,为Android提供身份的验证。

我们先来通过一张图来简单看下基于Binder的进程通信过程

img

Binder数据通信流程是,将数据从client端拷贝到内核空间,在内核空间中会提前通过mmap方式建立与server端的内存地址映射,通过内存地址映射server端可以直接访问内核空间中的数据,从而避免将数据拷贝到server端,提高进程间的通信速度。

在整个通信的过程中主要做的事情是:

  1. 通过/dev/binder打开binder驱动
  2. 通过mmap建立内存地址映射
  3. 通过ioctlbinder驱动交互,进行数据传输
  4. client使用BpBindertransact方法进行事务请求
  5. server使用BBinderonTransact方法来接收相应的事务

由于Android中主要使用Binder来进行service的注册与获取,所以为了更好的管理service的注册,使用了ServiceManager来进行统一管理service的注册。

service的注册过程中ServiceManager就相当于server端,内部开启loop循环,不断接收消息将注册的service保存到注册表svclist中。

最终关于Binder的整个大致流程如下图所示

img

其中clientserver位于应用层,ServiceManager位于用户空间,binder驱动位于内核空间。

对于开发者来说,用户空间与内核空间是透明的,我们只需关注应用层clientserver的实现,就可以方便的使用Binder的通信机制。

以上是对Binder的一个理论分析,接下来的一段时间,我将结合源码来分析service的注册过程,从而探索Binder的整个工作流程,感兴趣的读者可以关注一下。

更多Android进阶指南 可以扫码 解锁 《Android十大板块文档》

1.Android车载应用开发系统学习指南(附项目实战)

2.Android Framework学习指南,助力成为系统级开发高手

3.2023最新Android中高级面试题汇总+解析,告别零offer

4.企业级Android音视频开发学习路线+项目实战(附源码)

5.Android Jetpack从入门到精通,构建高质量UI界面

6.Flutter技术解析与实战,跨平台首要之选

7.Kotlin从入门到实战,全方面提升架构基础

8.高级Android插件化与组件化(含实战教程和源码)

9.Android 性能优化实战+360°全方面性能调优

10.Android零基础入门到精通,高手进阶之路

敲代码不易,关注一下吧。ღ( ´・ᴗ・` ) 🤔

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值