目录

android-进程间通信

android 进程间通信

android 进程间通信

android进程间通信的几种方式

管道 管道是单向的,管道一端连接着进程的输出,进程把数据放入管道,另一端连接进程的输入,进程从管道获取数据。实现数据通信。 信号 信号类似于通知,进程通过sigaction注册接收的信号,执行响应函数。 信号量+共享内存 信号量类似一个计数器,用来控制多个进程对共享资源的访问, 会有一个>0的初始值,每当有进程申请使用信号量,信号量就会-1,当减到0的时候,其他进程想要访问,就必须等待,当进程执行完工作后,会释放信号量,进行+1操作。 共享内存是一段物理内存,可以供给不同的进程访问。但是多个进程共享同一块区域,就会造成同时修改的问题,所以需要其他的机制来同步对共享空间的访问,如信号量。 消息队列 消息队列是一个消息的链表,存放在内核中并由消息队列标识符标识。比如说handler。 socket socket是将应用层数据从一个进程拷贝到另一个进程。zygote进程就是通过LocalSocket接收启动应用进程的通知。 binder binder更多的用在system_server进程与上层APP层的IPC交互。Intent、ContentpProvier、Messager、Broadcast、AIDL等都是基于Binder机制完成的跨进程通信。

进程间通信各方式的优缺点

管道:缓存区大小比较有限,一般为4k,只能传输无格式字节流。拷贝2次; 信号:不适用信息交换,更适用于进程中断控制。比如非法内存访问,杀死某个进程等。单向。 信号量:常作为锁机制。 共享内存:无需复制,可直接修改,速度快,同步问题需要同步工具解决。 消息队列:信息复制2次,额外的cpu小号,不适合频繁或信息量大的通信;拷贝2次; socket:作为更通用的接口,传输效率低;拷贝2次; binder:拷贝一次,但是身份标记有内核中添加,无法被篡改,因此更安全。c/s架构,稳定性好

IPC方式性能(拷贝次数)
管道2
信号2
信号量+共享内存0
消息队列2
socket2
binder1

binder优势说明

1. 性能方面 拷贝数据需要花时间,Binder只需拷贝一次,共享内存无需拷贝,其他的需要拷贝两次。 从速度上来说,Binder仅次于共享内存,优于Socket,消息队列,管道,信号,信号量等。 2. 特点方面 Binder: 基于C/S 架构,易用性高。 共享内存: 多个进程共享同一块内存区域,必然需要某种同步机制。 使用麻烦,容易出现数据不同步,死锁等问题。 Socket: socket作为一款通用接口,其传输效率低,开销大。 主要用在跨网络的进程间通信和本机上进程间的低速通信。 3. 安全性方面 Binder: (安全性高) 为每个APP分配不同UID,通过UID鉴别进程身份。 即支持实名Binder,又支持匿名Binder。 传统IPC: (不安全) 完全依赖上层协议,只能由用户在数据包中填入UID/PID。 访问接入点是开放的,任何程序都可以与其建立连接。

优势描述
性能拷贝一次,仅次于共享内存
稳定性基于C/S架构,职责明确,架构清晰
安全性为每个APP分配UID,进程的UID就是进程身份的重要标志,无法被篡改

Binder运行的机制原理

模块具有独立功能的程序,它可以单独被编译,但是不能独立运行,它在运行时被链接到内核作为内核的一部分运行。这样Android系统就可以通过动态添加一个内核模块运行在内核空间。这就是动态内核可加载模块(Loadable Kernel Module, LKM)。 这个运行在内核空间,负责用户进程通过binder实现通信的内核模块就叫Binder驱动(Binder Driver)。 1、binder驱动在内核空间创建一个数据接收缓存区,和接收进程用户空间地址建立内存映射关系。 2、继续在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区之间的映射关系。 3、发送方进程将数据拷贝到内核中的内核缓存区,通过映射关系,相当于把数据发送到了接收进程用户空间。这样就相当于完成了一次进程间的通信。 https://i-blog.csdnimg.cn/blog_migrate/3636ee7edc9ccd17919ead504121a146.png