进程间通信 就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。但是,系统空间 却是“ 公共场所” ,所以内核显然可以提供这样的条件。除此以外,那就是双方都可以访问的外设 了。在这个意义上,两个进程当然也可以通过磁盘上的普通文件 交换信息,或者通过“ 注册表 ” 或其它数据库中的某些表项和记录 交换信息。广义上这也是进程间通信的手段,但是一般都不把这算作“ 进程间通信” 。因为那些通信手段的效率太低了,而人们对进程间通信的要求是要有一定的实时性。
进程间通信主要包括管道, 系统IPC(包括消息队列,信号量,共享存储), SOCKET.
一. Linux 下进程间通信的几种主要手段简介:
1. 管道( Pipe )及有名管道( named pipe ): 管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;
管道包括三种 :1) 普通管道 PIPE, 通常有种限制 , 一是半双工 , 只能单向传输 ; 二是只能在父子进程间使用 . 2) 流管道 s_pipe: 去除了第一种限制 , 可以双向传输 . 3) 命名管道 :name_pipe, 去除了第二种限制 , 可以在许多并不相关的进程之间进行通讯 .
2. 信号( Signal ): 信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身; Linux 除了支持 Unix 早期信号语义函数 sigal 外,还支持语义符合 Posix.1 标准的信号函数 sigaction (实际上,该函数是基于 BSD 的, BSD 为了实现可靠信号机制,又能够统一对外接口,用 sigaction 函数重新实现了 signal 函数);
3. 报文( Message )队列(消息队列): 消息队列是消息的链接表,包括 Posix 消息队列 systemV 消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
4. 共享内存: 使得多个进程可以访问同一块内存空间,是最快的可用 IPC 形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。
5. 信号量( semaphore ): 主要作为进程间以及同一进程不同线程之间的同步手段。
6. 套接口( Socket ): 更为一般的进程间通信机制,可用于不同机器之间的进程间通信。起初是由 Unix 系统的 BSD 分支开发出来的,但现在一般可以移植到其它类 Unix 系统上: Linux 和 System V 的变种都支持套接字。
二.相关问题
FAQ1: 管道与文件描述符 , 文件指针的关系 ?
答 : 其实管道的使用方法与文件类似 , 都能使用 read,write,open 等普通 IO 函数 . 管道描述符类似于文件描述符 . 事实上 , 管道使用的描述符 , 文件指针和文件描述符最终都会转化成系统中 SOCKET 描述符 . 都受到系统内核中 SOCKET 描述符的限制 . 本质上 LINUX 内核源码中管道是通过空文件来实现 .
FAQ2: 管道的使用方法 ?
答 : 主要有下面几种方法 : 1)pipe, 创建一个管道 , 返回 2 个管道描述符 . 通常用于父子进程之间通讯 . 2)popen, pclose: 这种方式只返回一个管道描述符 , 常用于通信另一方是 stdin or stdout; 3)mkpipe: 命名管道 , 在许多进程之间进行交互 .
FAQ3: 管道与系统 IPC 之间的优劣比较 ?
答 : 管道 : 优点是所有的 UNIX 实现都支持 , 并且在最后一个访问管道的进程终止后 , 管道就被完全删除 ; 缺陷是管道只允许单向传输或者用于父子进程之间 .
系统 IPC: 优点是功能强大 , 能在毫不相关进程之间进行通讯 ; 缺陷是关键字 KEY_T 使用了内核标识 , 占用了内核资源 , 而且只能被显式删除 , 而且不能使用 SOCKET 的一些机制 , 例如 select,epoll 等 .
FAQ4: WINDOS 进程间通信与 LINUX 进程间通信的关系 ?
答 : 事实上 ,WINDOS 的进程通信大部分移植于 UNIX, WINDOS 的剪贴板 , 文件映射等都可从 UNIX 进程通信的共享存储中找到影子 .
FAQ5: 进程间通信与线程间通信之间的关系 ?
答 : 因为 WINDOWS 运行的实体是线程 , 狭义上的进程间通信其实是指分属于不同进程的线程之间的通讯 . 而单个进程之间的线程同步问题可归并为一种特殊的进程通信 . 它要用到内核支持的系统调用来保持线程之间同步 . 通常用到的一些线程同步方法包括 :Event, Mutex, 信号量Semaphore , 临界区资源等 .
三.进程间通信各种方式效率比较
类型 |
无连接 |
可靠 |
流控制 |
记录 |
消息类型优先级 |
普通 PIPE |
N |
Y |
Y |
|
N |
流 PIPE |
N |
Y |
Y |
|
N |
命名 PIPE(FIFO) |
N |
Y |
Y |
|
N |
消息队列 |
N |
Y |
Y |
|
Y |
信号量 |
N |
Y |
Y |
|
Y |
共享存储 |
N |
Y |
Y |
|
Y |
UNIX 流 SOCKET |
N |
Y |
Y |
|
N |
UNIX 数据包 SOCKET |
Y |
Y |
N |
|
N |
注 : 无连接 : 指无需调用某种形式的 OPEN, 就有发送消息的能力
流控制 : 如果系统资源短缺或者不能接收更多消息 , 则发送进程能进行流量控制
参考:
1.window进程间通信方式
http://www.cnblogs.com/hummersofdie/archive/2010/09/01/1814651.html
2.linux进程间通信
http://www.ibm.com/developerworks/cn/linux/l-ipc/part1/