10 views

进程间通信

一个大型应用程序,往往需要众多进程协作,进程间通信的重要性显而易见。Linux 下的进程通信手段基本上是从 UNIX 平台上的进程通信手段继承而来的,而对 UNIX 发展做出重大贡献的两大主力 —— AT&T 的贝尔实验室和 BSD (加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。前者对 UNIX 早期的进程间通信手段进行了系统的改进和扩充,形成了”system V IPC“,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接字(Socket)的进程通信机制。其中 UNIX IPC 包括管道,FIFO 和信号,System V IPC 包括 System V 消息队列、System V 信号灯和 System V 共享内存区,Posix IPC 包括 Posix 消息队列、Posix 信号灯 和 Posix 共享内存区。

(1)由于 UNIX 版本的多样性,电子电气工程协会(IEEE)开发了一个独立的 UNIX 标准,这个新的 ANSI UNIX 标准被称为计算机环境的可移植性操作系统界面(POSIX)。现有的大部分 UNIX 和流行版本遵循的都是 POSIX 标准,而 Linux 从诞生就遵循 POSIX 标准。

(2)BSD 并不是没有涉足单机内的进程通信(Socket 本身就可以用于单片机内的进程间通信)。事实上,很多 UNIX 版本的单机 IPC 留有 BSD 的痕迹。

进程间通信概述

目的

(1)数据传输:一个进程需要将它的数据发送给另外一个进程,发送的数据量在1B至几MB之间。

(2)共享数据:多个进程想要操作共享数据,若一个进程对共享数据进行修改,别的进程也能立即看到。

(3)通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(比如子进程终止时会发送信号通知父进程)。

(4)资源共享:多个进程之间共享同样的资源。为了做到这一点,需要内核提供锁和同步机制。

(5)进程控制:有些进程希望完全控制另一个进程的执行(如 Debug 进程),此时进程控制希望能够拦截另一个进程的所有信息和异常,并能够及时知道它的状态。

简介

通信方式说明
管道(Pipe)和有名管道(FiFO)管道可以用于具有亲缘关系进程间通信,有名管道克服了管道没有名字的限制,因此,它还可以用于无亲缘关系进程间通信。
信号(Signal)信号是比较复杂的通信方式,用于通知接收进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给本身;Linux 除了支持 UNIX 早期信号语义函数 signal 外,还支持语义符合 POSIX.1 标准的信号函数 sigaction (实际上,该函数是基于 BSD 的,BSD 为了在实现可靠信号机制的同时又能够统一对外接口,用 sigaction 函数重新实现了 signal 函数)。
信号是在软件层次上对终端机制的一种模拟是一种异步通信方式。
信号可以在直接进行用户空间进程和内核进程之间的交互,内核进程也可以利用它来通知用户空间进程发生了哪些系统上事件,它可以在任何时候发给某一进程,而无需知道该进程的状态。
如果该进程当前并未处于执行态,则该信号就由内核保存起来,直到该进程恢复执行再传递给它;如果一个信号被进程设置为阻塞,则该信号的传递被延迟,直到其阻塞不取消时才传递给进程。
消息队列消息队列是消息的链接表,包括 POSIX 消息队列和 System V 消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少、管道只能承接无格式字节流,以及缓冲区大小受限等缺点。
信号量(Semaphore)/信号灯信号量主要被用作进程间或同一进程不同线程之间的同步手段。信号量是用来解决进程之间同步与互斥问题的一种进程之间的通信机制,包括一个称为信号量的变量和在该信号量下等待资源的进程等待队列,以及对信号量进行的两个原子操作(PV 操作)。其中信号量对应于某一种资源,取一个非负的整型值。信号量的值是指当前可用的资源数量,若它等于 0 则意味着目前没有可用的资源。
共享内存(Shared Memory)共享内存可以说是最有用的进程间通信的方式,也是最快的。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到 A 和 B 各自的进程地址空间中。进程 A 可以即时看到进程 B 对共享内存中的更新,反之亦然。由于多个内存共享一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的复制。
套接字(Socket)套接字是更为一般的进程间通信机制,可用于不同机器之间的进程通信。起初是由 UNIX 系统的 BSD 分支开发出来的,但现在一般可以移植到其它类 UNIX 系统上,Linux 和 System V 的变种都支持套接字。

发表评论