进程间通信 就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是共享内存区。但是,系统空间 却是“公共场所”,所以内核显然可以提供这样的条件。除此以外,那就是双方都可以访问的外设 了。在这个意义上,两个进程当然也可以通过磁盘上的普通文件 交换信息,或者通过“注册表 ”或其它数据库中的某些表项和记录 交换信息。广义上这也是进程间通信的手段,但是一般都不把这算作“进程间通信”。因为那些通信手段的效率太低了,而人们对进程间通信的要求是要有一定的实时性。
进程间通信主要包括管道 , 系统 IPC( 包括消息队列 , 信号量 , 共享存储 ), SOCKET.
管道包括三种 :1) 普通管道 PIPE, 通常有种限制 , 一是半双工 , 只能单向传输 ; 二是只能在父子进程间使用 . 2) 流管道 s_pipe: 去除了第一种限制 , 可以双向传输 . 3) 命名管道 :name_pipe, 去除了第二种限制 , 可以在许多并不相关的进程之间进行通讯 .
系统 IPC 的三种方式类同 , 都是使用了内核里的标识符来识别 .
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, 就有发送消息的能力
流控制 : 如果系统资源短缺或者不能接收更多消息 , 则发送进程能进行流量控制
inux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验 室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。前者对Unix早期的进程间通信手段进行了系统的改进和扩充, 形成了“system V IPC”,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通信机制。Linux则把两者继承了下来,如图 示:
其中,最初Unix IPC包括:管道、FIFO、信号;System V IPC包括:System V消息队列、System V信号灯、System V共享内存区;Posix IPC包括: Posix消息队列、Posix信号灯、Posix共享内存区。有两点需要简单说明一下:1)由于Unix版本的多样性,电子电气工程协会(IEEE)开 发了一个独立的Unix标准,这个新的ANSI Unix标准被称为计算机环境的可移植性操作系统界面(PSOIX)。现有大部分Unix和流行版本都是遵循POSIX标准的,而Linux从一开始就遵 循POSIX标准;2)BSD并不是没有涉足单机内的进程间通信(socket本身就可以用于单机内的进程间通信)。事实上,很多Unix版本的单机 IPC留有BSD的痕迹,如4.4BSD支持的匿名内存映射、4.3+BSD对可靠信号语义的实现等等。
图一给出了linux 所支持的各种IPC手段,在本文接下来的讨论中,为了避免概念上的混淆,在尽可能少提及Unix的各个版本的情况下,所有问题的讨论最终都会归结到 Linux环境下的进程间通信上来。并且,对于Linux所支持通信手段的不同实现版本(如对于共享内存来说,有Posix共享内存区以及System V共享内存区两个实现版本),将主要介绍Posix API。
linux下进程间通信的几种主要手段简介:
下面将对上述通信机制做具体阐述。
附1:参考文献[2]中对linux环境下的进程进行了概括说明:
一般来说,linux下的进程包含以下几个关键要素:
进程和线程有时候并不完全区分,而往往根据上下文理解其含义。