1. 管道:
在创建时分配一个page大小的内存,缓存区大小比较有限; 单向 1页,即4K字节
getconf PAGESIZE
2. 消息队列:
信息复制两次,额外的CPU消耗;不合适频繁或信息量大的通信;
3. 共享内存:
无须复制,共享缓冲区直接付附加到进程虚拟地址空间,速度快;但进程间的同步问题操作系统无法实现,必须各进程利用同步工具解决;
4. 套接字:
作为更通用的接口,传输效率低,主要用于不同机器或跨网络的通信;本机也使用LocalSocket
例子:
Zygote进程的IPC采用的是Socket(套接字)机制
5. 信号量:
常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
6. 信号:
不适用于信息交换,更适用于进程中断控制,比如非法内存访问,杀死某个进程等;
例子:
Android中的Kill Process采用的signal(信号)机制
7.Binder
(1)从性能的角度
数据拷贝次数:Binder数据拷贝只需要一次,而管道、消息队列、Socket都需要2次,但共享内存方式一次内存拷贝都不需要;从性能角度看,Binder性能仅次于共享内存。
(2)从稳定性的角度
Binder架构 大于共享内存 。
Binder是基于C/S架构的;而共享内存实现方式复杂,没有客户与服务端之别, 需要充分考虑到访问临界资源的并发同步问题,否则可能会出现死锁等问题;
(3)从安全的角度
Android为每个安装好的应用程序分配了自己的UID,故进程的UID是鉴别进程身份的重要标志,前面提到C/S架构,Android系统中对外只暴露Client端,Client端将任务发送给Server端,Server端会根据权限控制策略,判断UID/PID是否满足访问权限,目前权限控制很多时候是通过弹出权限询问对话框,让用户选择是否运行。
在6.0之前的系统是在App第一次安装时,会将整个App所涉及的所有权限一次询问.
在Android 6.0做了调整,不再是安装时一并询问所有权限,而是在App运行过程中,需要哪个权限再弹框询问用户是否给相应的权限,对权限做了更细地控制
(4) 从公司战略的角度
Linux内核是开源的系统,所开放源代码许可协议GPL保护
对于上层的任何类库、服务、应用等运行在用户空间,一旦进行SysCall(系统调用),调用到底层Kernel,那么也必须遵循GPL协议。
Google巧妙地将GPL协议控制在内核空间,将用户空间的协议采用Apache-2.0协议(允许基于Android的开发商不向社区反馈源码),同时在GPL协议与Apache-2.0之间的Lib库中采用BSD证授权方法.
在Zygote孵化出system_server进程后,在system_server进程中出初始化支持整个Android framework的各种各样的Service,而这些Service从大的方向来划分,分为Java层Framework和Native Framework层(C++)的Service,几乎都是基于BInder IPC机制.
Java framework:
作为Server端继承(或间接继承)于Binder类,Client端继承(或间接继承)于Stub.Proxy类。
Native Framework层:
这是C++层,作为Server端继承(或间接继承)于BBinder类,Client端继承(或间接继承)于BpBinder。