关于进程之间的通信又很多种方式,不同的方式适用于不同的场景。
五种不同形式的IPC形式
1.消息传递(管道,FIFO和消息队列)
2.同步(互斥量,条件变量,读写锁,文件和记录锁,信号量)
3.共享内存(匿名的和具名的)
4.远程过程调用(Solaris门和Sun RPC 以及Android Binder)
5.通过计算机网络通信的程序,使用TCP/IP协议族API(跨网络IPC)
1.管道(pipe)
特点:单向的,具有“读取”端和“写入”端,容量有限。
2.Signal 实时信号量
3.Trace 跟踪
以上三种只适合父进程与子线程或者 兄弟进程之间的通信
4.System V 之 报文队列(Message)
5.System V 之 共享内存(ShareMessage)
实现共享内存的步骤
1.创建内存共享区
2.映射内存区
3.访问内存共享区
4.进程间通信
5.撤销内存映射区
6.删除内存共享区
6.System V 之 信号量 (Semaphore)
信号量与PV原语是由Dijkstra发明的,也是使用最为广泛的互斥方法之一。
P操作的执行过程
- 信号量S自减1
- 如果此时S依然>=0。说明共享资源此时是允许访问的,因而调用者直接返回,然后开始操作共享资源
- 否则的话就要等待别人主动释放资源,这种情况调用者会被加入等待序列,直到后续被唤醒
- 当某人释放了共享资源后,等待队列中的相关(取决于具体情况)对象会被唤醒,此时该对象具备访问资源的权力
- 信号量S自增1
- 此时如果S>0 ,说明当前没有希望访问资源的等待者,所以直接返回
- 否则V操作要唤醒等待队列中的相关对象,对应P操作中的最后一步。
7.基于TCP/IP的Socket IPC通信
8.同步
由Posix线程标准定义的两种同步形式:互斥锁(Mutex)、读写锁和条件变量。
Mutex 中文释义为互斥体。
它与Semaphore的区别:
如果允许多个变量同时访问,称为Counting Semaphores;而对于只允许取值0或1 则叫做Binary Semaphore 后者与Mutex具有相同的性质。
Mutex通常对某一排他资源的共享控制要么资源被占用(locked)要么就是可以访问(unlocked)。
两者没有本质区别
管程 :它实际是对Semaphore的扩展和延伸,是一种控制更为简单的同步手段
9.Unix Domain Socket
UDS是专门针对单机内的进程间通信提出来的,有时被称为IPC socket。实际实现机制不依赖于TCP/IP协议族。
- 服务端监听IPC请求
- 客户端发起IPC申请
- 双方成功建立IPC连接
- 客户端向服务端发送数据,证明IPC通信有效
10.System V 消息队列,信号量,和共享内存与 Posix 消息队列,信号量,和共享内存的区别?
11.android中的同步机制
Mutex
Condition:是条件变量在android系统中的实现类,
Barrier:同时基于Mutex和Condition实现的一个模型,
Android Binder
Socket作为一款通用的接口,其传输效率低,开销大,主要用在跨网络的进程间通信和本机进程间的低速通信。
消息队列和管道采取存储-转发方式,即数据先从发送方缓存区拷贝到内核开辟的缓冲区中,再从内核缓冲区拷贝到接收方缓存区,至少两次拷贝过程。
共享内存虽然无需拷贝,但是控制复杂,难以使用。
Binder只需拷贝一次
传统IPC没有任何安全做措施,完全依赖上层协议来确保。
这时android需要建立一套新的IPC机制来满足系统对通信的要求
Binder提供远程调用(Remote Procedure Cails)功能,可以让C++或者Java的对象实例从一个进程迁移到另一个进程,从而透明地实现跨进程的调用面向对象思想的引入将进程间通信转化为通过对某个Binder对象的引用调用该对象的方法,而其独特之处在于Binder对象是一个可以跨进程引用的对象,它的实体位于一个进程中,而它的引用却遍布于系统的各个进程之中。最诱人的是,这个引用和java里引用一样既可以是强类型,也可以是弱类型,而且可以从一个进程传给其它进程,让大家都能访问同一Server,就象将一个对象或引用赋值给另一个引用一样。Binder模糊了进程边界,淡化了进程间通信过程,整个系统仿佛运行于同一个面向对象的程序之中。形形色色的Binder对象以及星罗棋布的引用仿佛粘接各个应用程序的胶水,这也是Binder在英文里的原意
主要组成部分:Server ,Client ,ServiceManager 以及Binder驱动
1.binder驱动:
它位于内核,是通讯的核心,负责进程之间Binder通信的建立,Binder在进程之间的传递,Binder引用计数管理,数据包在进程之间的传递和交互等一系列底层支持。
2.ServiceManager(SMgr)
和DNS类似,SMgr的作用是将字符形式的Binder名字转化成Client中对该Binder的引用,使得Client能够通过Binder名字获得对Server中Binder实体的引用。
3.Server
Server创建一个Binder实体,Client在获得实体引用后,向Server传送数据,Server收到数据后做出相应的处理。
4.Client
Server向SMgr注册了Binder实体及其名字后,Client就可以通过名字获得该Binder的引用了。
完成一次通信的过程
1.客户端进程调用Stub接口
2.Stub根据系统的要求进行打包
3.内核来完成与服务器的具体交互,它负责将客户端的数据发送给服务端内核
4.服务端Stub解包,并调用与数据包匹配的进程
5.进程执行操作
6.服务端以上述步骤的逆向过程返回给客户端