Binder到底是什么鬼东西


前言

Binder,一个非常神奇的东西,普通开发过程中可能感觉根本见不到它的身影,但其实无处不在,例如contentProvider就是通过Binder实现


一、Binder是什么?

Binder,一个通过内存映射实现跨进程通信的东东,Android中一个进程空间分为用户空间内核空间,其中用户空间数据不可共享,内核空间数据可共享。
因此跨进程通信需要内核空间的支持,传统IPC通信例如管道,Socket等,它们是内核空间的一部分,可以直接拷贝,通过内容提供者进程copy_from_user()拷贝到内核空间,再通过copy_to_user()复制给内容接收方用户空间,实现的进程间通信。
但是Binder不属于Linux内核空间,不能直接进行内核空间的两次拷贝,所以需要借助Linux的动态内核可加载模块机制。

二、传统IPC通信方式

Linux现有的进程通信手段有以下几种:

  1. 管道:在创建时分配一个page大小的内存,缓存区大小比较有限; 消息队列:信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信;
  2. 共享内存:无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决;
  3. 套接字:作为更通用的接口,传输效率低,主要用于不通机器或跨网络的通信;
  4. 信号量:常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段;
  5. 信号: 不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等;

三、Binder的优点

既然有现有的IPC方式,为什么重新设计一套Binder机制呢。主要是出于以上三个方面的考量:

  • 高性能:从数据拷贝次数来看Binder只需要进行一次内存拷贝,而管道、消息队列、Socket都需要两次,共享内存不需要拷贝,Binder的性能仅次于共享内存。
  • 稳定性:上面说到共享内存的性能优于Binder,那为什么不适用共享内存呢,因为共享内存需要处理并发同步问题,控制负责,容易出现死锁和资源竞争,稳定性较差。而Binder基于C/S架构,客户端与服务端彼此独立,稳定性较好。
  • 安全性:我们知道Android为每个应用分配了UID,用来作为鉴别进程的重要标志,Android内部也依赖这个UID进行权限管理,包括6.0以前的固定权限和6.0以后的动态权限,传荣IPC只能由用户在数据包里填入UID/PID,这个标记完全是在用户空间控制的,没有放在内核空间,因此有被恶意篡改的可能,因此Binder的安全性更高。

四、内存映射

Binder涉及的内存映射通过mmap()实现,内存映射简单的讲,就是将用户空间的一块内存区域映射到内核空间。映射关系建立后,用户对这块内存区域的修改可以直接反映到内核空间,反之内核空间对这段区域的修改也能直接反映到用户空间。

五、一次完整的Binder通信流程

一次完整的Binder通信过程主要如下:

  • 首先Binder驱动在内核空间创建一个数据接收缓存区
  • 接着在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区间的映射关系,并且建立内核中数据接收缓存区和接收进程用户空间地址的映射关系
  • 发送方通过copy_from_user()将数据拷贝到内核空间中的内核缓存区,由于建立了内存映射,就相当于把数据拷贝给了接收进程的用户空间,这样就完成了一次进程间的数据通信

完整的流程图如下(图片来源):
跨进程通信流程

六、Binder通讯模型

Binder是基于C/S架构的,其中定义了4个模型:Client、Server、Binder驱动、ServiceManager

  • Binder驱动,负责将Client请求转发到具体的Server中处理,并将Server返回数据发送给Client,是Client、Server、serviceManager的中间人
  • ServiceManager,管理Server的注册与查询,负责将Client请求的Binder描述符转化为具体的Server地址,以便Binder驱动能转发给具体的Server
  • Server向serviceManager注册,Server通过Binder驱动向serviceManager申请注册,声明可以对外提供的服务;serviceManager中保留一份映射表
  • Client向ServiceManager请求Server的Binder引用;Client想要请求Server数据时,先要通过Binder驱动向serviceManager请求server的Binder引用
  • 向具体的server发送请求;Client拿到Binder的代理对象后,就可以通过Binder驱动,和具体的Server进行通信了
  • Server返回结果;Server响应请求后,需要通过Binder驱动再次将结果返回给Client
  • 注意Binder驱动 & ServiceManager进程 属于Android基础架构(即系统已经实现好了);而Client 进程Server 进程 属于Android应用层(需要开发者自己实现)

流程图如下(图片来源):
在这里插入图片描述

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
千里马8年Android系统及应用开发经验,曾担任过美国unokiwi公司移动端技术总监兼架构师,对系统开发,性能优化,应用高级开发有深入的研究,Android开源定制ROM Lineage的贡献者之一,国内首家线下开辟培训Android Framework课程,拥有2年的Android系统培训经验。成为腾讯课堂专业负责android framework课程分享第一人,致力于提高国内android Framework水平Android Framework领域内是国内各大手机终端科技公司需要的人才,应用开发者都对Android系统充满着好奇,其中的binder是重中之重,都说无binderAndroidbinde是Android系统的任督二脉。课程水平循序渐进,由中级再到高级,满足各个层次水平的android开发者。1、灵活使用binder跨进程通信,在app端对它的任何api方法等使用自如2、可以单独分析android系统源码中任何binder部分,分析再也没有难度3、掌握binder驱动本质原理,及对应binder驱动怎么进行跨进程通信,及内存等拷贝方式数据等4、对binder从上层的java app端一直到最底层的内核binder驱动,都可以顺利理通5、针对系统开发过程中遇到的binder报错等分析方法,及binder bug案例学习6、针对面试官任何的binder问题都可以对答自如7、socket这种跨进程通信实战使用8、针对android源码中使用的socket源码轻松掌握9、android系统源码中最常见的socketpair中双向跨进程通信10、使用socket实现一个可以让app执行shell命令的程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值