Binder的基本介绍,Linux进程通信的几种方式、手写进程通信代码(一)

Binder的概述:

  • Binder是干嘛的?
  • 为什么选择Binder作为最主要的IPC通信机制
  • 绘制Binder的通信架构图,讲述原理
  • 手写一个AIDL

Linux系统的通信方式

先介绍Linux进程通信的方式:

  • 管道
  • Socket
  • 共享内存
  • 信号
1、管道
  • 半双工,单向的,数据只能在一个方向流,要么读,要么写 pipe(fds):Linux提供的api,可以生成两个字符,一个读一个写
  • 一般在父子进程之间使用 (无名管道)
  • 如果知道管道名字,两个进程可以交互
    原理图: 先生成两个描述符:读写。 操作的时候会关一个
    在这里插入图片描述
2、Socket 注意:本地的socket不是网络的sokcet
  • 全双工的,可读可写
  • 任意两个进程都可以进程交互
  • 创建的时候需要指定一个路径,只要公开路径就可以进行通信了
共享内存
  • 很快,不需要多次拷贝
  • 拿到文件描述符,直接映射到两个进程的内存空间,一个进程往里面写,另一个就能得到
信号
  • 单向的,发出去之后怎么处理是别人的事
  • 只能带个信号,不能带别的参数
  • 知道进程的pid,就可以发信号了,一次可以群发。
  • 注意有权限限制,要么root权限, 要么同一个进程uid相同
总结:
  • 进程间通信其实还有两个因素: 性能、传输效率和安全

管道: 性能、效率问题,采用内存缓冲的方式,先从发送方的缓冲区拷贝到内核开辟的缓存区,在从内核缓冲区拷贝到接收方的缓冲区,至少拷贝两次。

Sokcet: 传输效率低,开销比较大,也存在安全问题。Android为每个应用分配一个UID,所以UID是标记进程的方式,但是这个会放在数据包中,可以被恶意的拦截,进行随意的入侵。

共享内存: 虽然不需要拷贝,但是也存在安全的问题。

总结:所以Android需要一种高效、安全性能高的通信方式! Binder做到的安全:ipc标记在内核中添加


二、进程隔离

为什么要设计进程隔离?

进程之间是无法直接进行交互的,每个进程独享自己的数据。 主要是为了保证 自身系统的安全稳定性,将系统内核空间和用户空间分开来,保证用户进程崩溃时,不会影响整个系统。

用户空间和内核空间
用户空间(不可共享空间):表示进程运行在一个特定的操作模式中,没有接触物理内存或设备的权限
内核空间(可共享空间):表示独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限

总结: 为了保证安全性,他们之间是隔离的,所以用户空间的进程要进行交互,需要通过内核。

  • Linux的虚拟内存机制导致内存的隔离,进而导致进程隔离
  • 进程隔离的出现导致对内存的操作被划分为用户空间和内核空间
  • 用户空间需要跨权限去访问内核空间,必须使用系统调用去实现
  • 系统调用需要借助内核模块/驱动去完成

三、C/S结构

四、Binder通信模型:

Binder基于C/S的结构下,定义了4个角色:Server、Client、ServerManager、Binder驱动,其中前三者是在用户空间的,也就是彼此之间无法直接进行交互,Binder驱动是属于内核空间的 ,属于整个通信的核心,虽然叫驱动,但是实际上和硬件没有太大关系,只是实现的方式和驱动差不多,驱动负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。
在这里插入图片描述
从上图很清晰的可以看出来整个的交互过程,原本从SM中拿到binder的引用,通过Binder驱动层的处理之后,返回给了client一个代理对象,实际上如果client和server处于同一个进程,返回的就是当前binder对象,如果client和server不处于同一个进程,返回给client的就是一个代理对象


自己写一个跨进程通信:

首先先理解几个关键词的概念:

IBinder : IBinder 是一个接口,代表了一种跨进程通信的能力。只要实现了这个借口,这个对象就能跨进程传输。
IInterface : IInterface 代表的就是 Server 进程对象具备什么样的能力(能提供哪些方法,其实对应的就是 AIDL 文件中定义的接口)
Binder : Java 层的 Binder 类,代表的其实就是 Binder 本地对象。BinderProxy 类是 Binder 类的一个内部类,它代表远程进程的 Binder 对象的本地代理;这两个类都继承自 IBinder, 因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder 驱动会自动完成这两个对象的转换。
Stub : AIDL 的时候,编译工具会给我们生成一个名为 Stub 的静态内部类;这个类继承了 Binder, 说明它是一个 Binder 本地对象,它实现了 IInterface 接口,表明它具有 Server 承诺给 Client 的能力;Stub 是一个抽象类,具体的 IInterface 的相关实现需要开发者自己实现。

public interface PersonManger extends IInterface {
   
    void addPerson(Person mPerson);
    List<Person> getPersonList();
}
// server端的binder实体对象,其实就是aidl自动生成的Stub对象

public abstract class BinderObj extends Binder implements PersonManger {
   
    public static final String DESCRIPTOR = "com.example.taolin.hellobinder";
    public static final int TRANSAVTION_getPerson = IBinder.FIRST_CALL_TRANSACTION;
    public static final int TRANSAVTION_addPerson = IBinder.FIRST_CALL_TRANSACTION + 1;
    public static PersonManger asInterface(IBinder mIBinder){
   
        IInterface iInterface = mIBinder.queryLocalInterface(DESCRIPTOR);
        if (null!=iInterface&&iInterface instanceof PersonManger){
   
            return (PersonManger)iInterface
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值