传统IPC传输数据
Android系统内核是Linux,每个进程有自己的虚拟地址空间,在32位系统下最大是4GB,其中3GB为用户空间,1GB为内核空间;每个进程用户空间相对独立,而内核空间是一样的,可以共享。但是用户空间和内核空间是隔离开的,无法互相访问,传统的IPC传输数据需要借助copy_from_user和copy_to_user两个系统调用,把用户/内核空间内存中的数据拷贝到内核/用户空间的内存中,这样的话,如果两个进程需要进行一次单向通信则需要进行两次拷贝
Binder传输数据
Binder单次通信只需要进行一次拷贝,因为它使用了内存映射(memory map),将一块物理内存(若干个物理页)分别映射到接收端用户空间和内核空间,达到用户空间和内核空间共享数据的目的
- 数据发送(client)进程通过copy_from_user()将数据从用户空间拷贝到了内核空间
- 数据接收(server)进程通过mmap将内核空间的内存地址映射到了用户空间
- 只要client将数据拷贝到内核空间,那么server进程就可以直接读取到内核空间的数据,无需再次拷贝
Binder驱动是什么
传统的 Linux 通信机制,比如 Socket,管道等都是内核支持的。但是 Binder 并不是 Linux 内核的一部分,它是怎么做到访问内核空间的呢?Linux 的动态可加载内核模块(Loadable Kernel Module,LKM)机制解决了这个问题:模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被链接到内核作为内核的一部分在内核空间运行。这样,Android系统可以通过添加一个内核模块运行在内核空间,用户进程之间通过这个模块作为桥梁,就可以完成通信了。这个运行在内核空间的,负责各个用户进程通过 Binder 通信的内核模块叫做 Binder 驱动
Binder与传统IPC对比
传统的Linux IPC机制:
- 管道:在创建时分配一个page大小的内存,缓存区大小比较有限
- 消息队列:信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信
- 共享内存:无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决
- 套接字:作为更通用的接口,传输效率低,主要用于不通机器或跨网络的通信
- 信号量:常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段
- 信号: 不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了