Binder简介

1、Binder是android重要的IPC通信,与传统的IPC(Linux 内存共享,管道,信号量,消息队列,socket等)通信相比,有以下特色:java

一、简洁快速android

二、内存消耗小缓存

三、进程开销小安全

四、传输性能高,传输过程只需一次拷贝(共享内存的方式)服务器

五、进程间同步调用(socket是异步),Binder对象是一个能够跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍及于系统的各个进程之中,经过Binder对象调用其提供的方法和调用其它任何本地对象的方法并没有区别。网络

六、传输安全性高,Binder是基于Client-Server通讯模式,为发送发添加UID/PID身份,既支持实名Binder也支持匿名Binder,安全性高(传统IPC没有任何安全措施,如socket的ip地址或文件名都是开放的,)框架

其中最重要的是传输性能高,安全性强,能够同步调用。异步

(socket做为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通讯和本机上进程间的低速通讯)socket

 

2、binder与传统IPC方式数据拷贝次数对比性能

                                      表 1

IPC

数据拷贝次数

共享内存

0

Binder

1

Socket/管道/消息队列

2

 3、Binder只需一次拷贝的‘秘密’

  Binder采用的内存映射和接收缓存区管理策略:由Binder驱动负责管理数据接收缓存。Binder驱动实现了mmap()系统调用,是用来建立数据接收的缓存空间,mmap()的使用以下:

fd = open("/dev/binder", O_RDWR);

mmap(NULL, MAP_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);

这样Binder的接收方就有了一片大小为MAP_SIZE的接收缓存区。mmap()的返回值是内存映射在用户空间的地址,不过这段空间是由驱动管理,用户没必要也不能直接访问(映射类型为PROT_READ,只读映射)。接收缓存区映射好后就能够作为缓存池接收和存放数据了。驱动为接收方分担了最为繁琐的任务在效率上,因为mmap()分配的内存是映射在接收方用户空间里的,全部整体效果就至关于对有效负荷数据作了一次从发送方用户空间到接收方用户空间的直接数据拷贝,省去了内核中暂存这个步骤,提高了一倍的性能。为了实现用户空间到用户空间的拷贝,mmap()分配的内存除了映射进了接收方进程里,还映射进了内核空间。因此调用copy_from_user()将数据拷贝进内核空间也至关于拷贝进了接收方的用户空间,这就是Binder只需一次拷贝的‘秘密’

 

4、Binder 通讯模型

Binder框架定义了四个角色:Server,Client,ServiceManager(之后简称SMgr)以及Binder驱动。其中Server,Client,SMgr运行于用户空间,驱动运行于内核空间。这四个角色的关系和互联网相似:Server是服务器,Client是客户终端,SMgr是域名服务器(DNS),驱动是路由器。

 

3.1 Binder 驱动

和路由器同样,Binder驱动虽然默默无闻,倒是通讯的核心。尽管名叫‘驱动’,实际上和硬件设备没有任何关系,只是实现方式和设备驱动程序是同样的。它工做于内核态,驱动负责进程之间Binder通讯的创建,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。

3.2 ServiceManager 与实名Binder

和DNS相似,SMgr的做用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client可以经过Binder名字得到对Server中Binder实体的引用。注册了名字的Binder叫实名Binder,就象每一个网站除了有IP地址外还有本身的网址。Server建立了Binder实体,为其取一个字符形式,可读易记的名字,将这个Binder连同名字以数据包的形式经过Binder驱动发送给SMgr,通知SMgr注册一个名叫张三的Binder,它位于某个Server中。驱动为这个穿过进程边界的Binder建立位于内核中的实体节点以及SMgr对实体的引用,将名字及新建的引用打包传递给SMgr。SMgr收数据包后,从中取出名字和引用填入一张查找表中。

细心的读者可能会发现其中的蹊跷:SMgr是一个进程,Server是另外一个进程,Server向SMgr注册Binder必然会涉及进程间通讯。当前实现的是进程间通讯却又要用到进程间通讯,这就好象蛋能够孵出鸡前提倒是要找只鸡来孵蛋。Binder的实现比较巧妙:预先创造一只鸡来孵蛋:SMgr和其它进程一样采用Binder通讯,SMgr是Server端,有本身的Binder对象(实体),其它进程都是Client,须要经过这个Binder的引用来实现Binder的注册,查询和获取。SMgr提供的Binder比较特殊,它没有名字也不须要注册,当一个进程使用BINDER_SET_CONTEXT_MGR命令将本身注册成SMgr时Binder驱动会自动为它建立Binder实体(这就是那只预先造好的鸡)。其次这个Binder的引用在全部Client中都固定为0而无须经过其它手段得到。也就是说,一个Server若要向SMgr注册本身Binder就必需经过0这个引用号和SMgr的Binder通讯。类比网络通讯,0号引用就比如域名服务器的地址,你必须预先手工或动态配置好。要注意这里说的Client是相对SMgr而言的,一个应用程序多是个提供服务的Server,但对SMgr来讲它仍然是个Client。

3.3 Client 得到实名Binder的引用

Server向SMgr注册了Binder实体及其名字后,Client就能够经过名字得到该Binder的引用了。Client也利用保留的0号引用向SMgr请求访问某个Binder:我申请得到名字叫张三的Binder的引用。SMgr收到这个链接请求,从请求数据包里得到Binder的名字,在查找表里找到该名字对应的条目,从条目中取出Binder的引用,将该引用做为回复发送给发起请求的Client。从面向对象的角度,这个Binder对象如今有了两个引用:一个位于SMgr中,一个位于发起请求的Client中。若是接下来有更多的Client请求该Binder,系统中就会有更多的引用指向该Binder,就象java里一个对象存在多个引用同样。并且相似的这些指向Binder的引用是强类型,从而确保只要有引用Binder实体就不会被释放掉。经过以上过程能够看出,SMgr象个火车票代售点,收集了全部火车的车票,能够经过它购买到乘坐各趟火车的票-获得某个Binder的引用。

3.4 匿名 Binder

并非全部Binder都须要注册给SMgr广而告之的。Server端能够经过已经创建的Binder链接将建立的Binder实体传给Client,固然这条已经创建的Binder链接必须是经过实名Binder实现。因为这个Binder没有向SMgr注册名字,因此是个匿名Binder。Client将会收到这个匿名Binder的引用,经过这个引用向位于Server中的实体发送请求。匿名Binder为通讯双方创建一条私密通道,只要Server没有把匿名Binder发给别的进程,别的进程就没法经过穷举或猜想等任何方式得到该Binder的引用,向该Binder发送请求。

相关文章
相关标签/搜索