Android8.0.0-r4的Binder进程间通信机制简介

1、概念普及

  • Linux进程 
        进程定义:进程是一个具有独立功能的程序的一次运行活动。其实进程有很多的定义,这个只是其中一种,那么android中的app就是一个程序,一个运行中的app就会至少对应一个进程,进程是一种动态的概念,程序是一种静态的概念。

  • 进程隔离 
        进程隔离是为保护操作系统中进程互不干扰而设计的一组不同硬件和软件的技术。这个技术是为了避免进程A写入进程B的情况发生。 进程的隔离实现,使用了虚拟地址空间。进程A的虚拟地址和进程B的虚拟地址不同,这样就防止进程A将数据信息写入进程B。以上来自维基百科;操作系统的不同进程之间,数据不共享;对于每个进程来说,它都天真地以为自己独享了整个系统,完全不知道其他进程的存在;因此一个进程需要与另外一个进程通信,需要某种系统机制才能完成。

  • Linux进程空间 
        Linux的虚拟地址空间范围为0~4G,Linux内核将这4G字节的空间分为两部分,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF)供内核使用,称为“内核空间”。而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF)供各个进程使用,称为“用户空间。因为每个进程可以通过系统调用进入内核,因此,Linux内核由系统内的所有进程共享。于是,从具体进程的角度来看,每个进程可以拥有4G字节的虚拟空间。

  • 用户空间/内核空间 
        详细解释可以参考Kernel Space Definition;简单理解如下: 
        Linux Kernel是操作系统的核心,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。对于Kernel这么一个高安全级别的东西,显然是不容许其它的应用程序随便调用或访问的,所以需要对Kernel提供一定的保护机制,这个保护机制用来告诉那些应用程序,你只可以访问某些许可的资源,不许可的资源是拒绝被访问的,于是就把Kernel和上层的应用程序抽像的隔离开,分别称之为Kernel Space和User Space。

  • 共享资源 
        内核由系统内的进程共享,进程在各自独立的地址空间中运行,进程间的资源是不共享的。进程间如果想要共享资源,想像在同一进程中那样调用方法,传递参数就需要使用一些手段,进程之间共享数据需要用mmap或者进程间通信机制。

  • 系统调用/内核态/用户态 
        虽然从逻辑上抽离出用户空间和内核空间;但是不可避免的的是,总有那么一些用户空间需要访问内核的资源
    用户空间访问内核空间的唯一方式就是系统调用;通过这个统一入口接口,所有的资源访问都是在内核的控制下执行,以免导致对用户程序对系统资源的越权访问,从而保障了系统的安全和稳定。 
        当一个任务(进程)执行系统调用而陷入内核代码中执行时,称进程处于内核运行态(或简称为内核态)此时处理器处于特权级最高的(0级)内核代码中执行。当进程在执行用户自己的代码时,则称其处于用户运行态(用户态)。即此时处理器在特权级最低的(3级)用户代码中运行。处理器在特权等级高的时候才能执行那些特权CPU指令。

  • 内核模块/驱动 
        通过系统调用,用户空间可以访问内核空间,用户空间与另外一个用户空间进行通信的方法是让操作系统内核添加支持;传统的Linux通信机制,比如Socket,管道等都是内核支持的;但是Binder并不是Linux内核的一部分,它是怎么做到访问内核空间的呢?Linux的动态可加载内核模块(Loadable Kernel Module,LKM)机制解决了这个问题;模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行。这样,Android系统可以通过添加一个内核模块运行在内核空间,用户进程之间的通过这个模块作为桥梁,就可以完成通信了。  在Android系统中,这个运行在内核空间的,负责各个用户进程通过Binder通信的内核模块叫做Binder驱动;

  • Linux现有手段 
        Linux已经拥有的进程间通信IPC手段包括(Internet Process Connection): 管道(Pipe)、信号(Signal)和跟踪(Trace)、插口(Socket)、报文队列(Message)、共享内存(Share Memory)和信号量(Semaphore)


2、Binder优势
1、复杂度 
    目前linux支持的IPC包括传统的管道,System V IPC,即消息队列/共享内存/信号量,以及socket中只有socket支持Client-Server的通信方式。当然也可以在这些底层机制上架设一套协议来实现Client-Server通信,但这样增加了系统的复杂性,在手机这种条件复杂,资源稀缺的环境下可靠性也难以保证。
2、效率 
    socket作为一款通用接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机上进程间的低速通信。消息队列和管道采用存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓存区中(copy_form_user),然后再从内核缓存区拷贝到接收方缓存区(copy_to_user),至少有两次拷贝过程。共享内存虽然无需拷贝,但控制复杂,难以使用。 
Binder进程间通信机制在进程间传输数据时,只需要执行一次数据拷贝操作,因此,它不仅提高了效率,而且节省了时间。
3、安全性 
    终端用户不希望从网上下载的程序在不知情的情况下偷窥隐私数据,连接无线网络,长期操作底层设备导致电池很快耗尽等等。传统IPC没有任何安全措施,完全依赖上层协议来确保。首先传统IPC的接收方无法获得对方进程可靠的UID和PID(用户ID进程ID),从而无法鉴别对方身份。Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志。使用传统IPC只能由用户在数据包里填入UID和PID,但这样不可靠,容易被恶意程序利用。可靠的身份标记只有由IPC机制本身在内核中添加。其次传统IPC访问接入点是开放的,无法建立私有通道。比如命名管道的名称,systemV的键值,socket的ip地址或文件名都是开放的,只要知道这些接入点的程序都可以和对端建立连接,不管怎样都无法阻止恶意程序通过猜测接收方地址获得连接。
    基于以上原因,Android需要建立一套新的IPC机制来满足系统对通信方式,传输性能和安全性的要求,这就是Binder。Binder基于Client-Server通信模式,传输过程只需一次拷贝,为发送发添加UID/PID身份,既支持实名Binder也支持匿名Binder,安全性高。 

表 1 各种IPC方式数据拷贝次数

IPC

数据拷贝次数

共享内存

0

Binder

1

Socket/管道/消息队列

2


参考:

http://blog.csdn.net/freekiteyu/article/details/70082302
http://blog.csdn.net/omyrobin/article/details/78832654
https://blog.csdn.net/universus/article/details/6211589
https://blog.csdn.net/ma969070578/article/details/45871323/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值