进程间通讯方式【转】

 

  这部分参考文献2:详细内容打开连接看html

   程序员必须让拥有依赖关系的进程集协调,这样才能达到进程的共同目标。可使用两种技术来达到协调。第一种技术在具备通讯依赖关系的两个进程间传递信息。这种技术称作进程间通讯(interprocess communication)。第二种技术是同步,当进程间相互具备合做依赖时使用。这两种类型的依赖关系能够同时存在。linux

通常而言,进程有单独的地址空间。咱们能够了解下可执行程序被装载到内存后创建的一系列映射等理解这一点。如此以来意味着若是咱们有两个进程(进程A和进程B),那么,在进程A中声明的数据对于进程B是不可用的。并且,进程B看不到进程A中发生的事件,反之亦然。若是进程A和B一块儿工做来完成某个任务,必须有一个在两个进程间通讯信息和时间的方法。咱们这里能够去看看基本的进程组件。注意进程有一个文本、数据以及堆栈片段。进程可能也有从自由存储空间中分配的其它内存。进程所占有的数据通常位于数据片段、堆栈片段或进程的动态分配内存中。数据对于其它进程来讲是受保护的。为了让一个进程访问另一个进程的数据,必须最终使用操做系统调用。与之相似,为了让一个进程知道另外一个进程中文本片段中发生的事件,必须在进程间创建一种通讯方式。这也须要来自操做系统API的帮助。当进程将数据发送到另外一进程时,称作IPC(interprocess communication,进程间通讯)。程序员

下面先列举几种不一样类型的进程间通讯方式:服务器

 

进程间通讯 描述
 环境变量/文件描述符 子进程接受父进程环境数据的拷贝以及全部文件描述符。父进程能够在它的数据片段或环境中设置必定的变量,同时子进程接收这些值。父进程能够打开文件,同时推动读/写指针的位置,并且子进程使用相同的偏移访问该文件。
命令行参数  在调用exec或派生函数期间,命令行参数能够传递给子进程。
管道 用于相关和无关进程间的通讯,并且造成两个进程间的一个通讯通道,一般使用文件读写程序访问。

共享内存(动态数据交换,Dynamic data exchange)网络

使用客户机/服务器模型(C/S),服务器对客户的数据

或动做请求做出反应。session

DDE 两个进程以外的内存块,两个进程都可以访问它。

        

1、环境变量、文件描述符:数据结构

当建立一个子进程时,它接受了父进程许多资源的拷贝。子进程接受了父进程的文本、堆栈app

以及数据片段的拷贝。子进程也接受了父进程的环境数据以及全部文件描述符的拷贝。子进socket

程从父进程继承资源的过程创造了进程间通讯的一个机会。父进程能够在它的数据片段或环函数

境中设置必定的变量,子进程因而接受这些值。一样,父进程也能够打开一个文件,推动到

文件内的指望位置,子进程接着就能够在父进程离开读/写指针的准确位置访问该文件。

 

这类通讯的缺陷在于它是单向的、一次性的通讯。也就是说,除了文件描述外,若是子进程

继承了任何其它数据,也仅仅是父进程拷贝的全部数据。 一旦建立了子进程,由子进程对

这些变量的任何改变都不会反映到父进程的数据中。一样,建立子进程后,对父进程数据的

任何改变也不会反映到子进程中。因此,这种类型的进程间通讯更像指挥棒传递。一旦父进

程传递了某些资源的拷贝,子进程对它的使用就是独立的,必须使用原始传递资源。

 

2、命令行参数:

经过命令行参数(command-line argument)能够完成另外一种单向、一次性的进程间通讯

我前面的文章已经提到过使用命令行参数。命令行参数在调用一个exec或派生调用操做系

统时传递给子进程。命令行参数一般在其中一个参数中做为NULL终止字符串传递给exec

或派生函数调用。这些函数能够按单向、一次性方式给子进程传递值。WINDOWS有调用执行

exe程序的API。你们能够去参考一下ShellExecuteA函数相关。

 

3、管道通讯:

继承资源以及命令行参数是最简单形式的进程间通讯。它们同时有两个主要限制。除了文件

描述符外,继承资源是IPC的单向、一次性形式。传递命令参数也是单向、一次性的IPC

方法。这些方法也只有限制于关联进程,若是不关联,命令行参数和继承资源不能使用。还

有另外一种结构,称作管道(Pipe),它能够用于在关联进程间以及无关联进程间进行通讯。

管道是一种数据结构,像一个序列化文件同样访问。它造成了两个进程间的一种通讯渠道。

管道结构经过使用文本和写方式来访问。若是进程A但愿经过管道发送数据给进程B,那么

进程A向管道写入数据。为了让进程B接收此数据,进程B必须读取管道,与命令行参数的

IPC形式不同。管道能够双向通讯。两进程间的数据流是双向通讯的。管道能够在程序的

整个执行期间使用,在进程间发送和接收数据。因此,管道充当可访问管道的进程间的一种

可活连接,有两种基本管道类型:

1.  匿名管道

2.  命名管道

匿名管道

上面的图能够看出在没有管道时,两进程是不能互写的。

匿名管道

创建管道后就能够相互通讯了。

    

4、 共享内存

共享内存也能够实现进程间的通讯。进程须要能够被其余进程浏览的内存块。但愿访问这个内存块的其余进程请求对它的访问,或由建立它的进程授予访问内存块的权限。能够访问特定内存块的全部进程对它具备即时可见性。共享内存被映射到使用它的每一个进程的地址空间。因此,它看起来像是另外一个在进程内声明的变量。当一个进程写共享内存,全部的进程都当即知道写入的内容,并且能够访问。

 

进程间共享内存的关系与函数间全局变量的关系类似。程序中的全部函数均可以使用全局变量的值。一样,共享内存块能够被正在执行的全部进程访问。内存块可能共享一个逻辑地址,进程也能够共享某些物理地址。

 

共享内存块的建立必须由一个系统API调用来完成。在WIN32环境中,使用CreateFileMapping()、MapViewOfFile()以及MapViewOfFileEx() API能很好地完成。

 

共享内存分配位于WIN32系统中2~3GB地址范围内。一旦调用MapViewOfFile()和MapViewOfFileEx(),共享文件映射对象的全部进程均可以当即访问此内存块,并且在须要时,能够读写此内存块。

 

5、动态数据交换

动态数据交换( dynamic data exchange ) 是当今可用的进程间通讯最强大和完善的形式之一。动态数据交换使用消息传递、共享内存、事务协议、客户/服务器范畴、同步规则以及会话协议来让数据和控制信息在进程间流动。动态数据交换对话( dynamic data exchange session, DDE )的基本模型是客户、服务器。服务器对来自客户的数据或动做做出反应。客户和服务器能够以多种关系来通讯。

 

一个服务器能够与任意数量的客户通讯。一个客户也能够与任意数量的服务器通讯。单个DDE代理既能够是客户,也能够是服务器。也就是说,进程能够从一个正为另外一个进程执行服务的DDE代理请求服务。

   



下部分参考文献1: 

  进程间通讯主要包括管道, 系统IPC(包括消息队列,信号量,共享存储), SOCKET.

  Windows系统进程间通讯

Windows提供了多种机制,使得应用程序之间可以快速、方便地共享数据和信息。这些机制包括RPC、COM、OLE、DDE、消息、剪切板、邮件槽、管道、套接字等。可是,若是在同一台机器上的多个进程间进行通讯的话,那么上面的机制都与共享内存有关。这在Windows上称做内存映射文件。

  这种数据共享机制是经过让两个或多个进程映射同一文件映射对象的视图来实现,这意味着进程间共享相同的物理存储页面。所以,当一个进程在文件映射对象的视图中写入数据时,其余的进程会在它们的视图中马上看到变化。可是,对多个进程共享同一个文件映射对象来讲,全部进程使用的文件映射对象的名称必须彻底相同[1]

 

Linux系统进程间通讯

 

  linux下的进程通讯手段基本上是从Unix平台上的进程通讯手段继承而来的。而对Unix发展作出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通讯方面的侧重点有所不一样。前者对Unix早期的进程间通讯手段进行了系统的改进和扩充,造成了“system V IPC”,通讯进程局限在单个计算机内;后者则跳过了该限制,造成了基于套接口(socket)的进程间通讯机制。Linux则把二者继承了下来。

  Linux下的进程间通讯机制大体包括:管道、信号(在Windows上成为消息)、信号队列(实际是消息链表)、共享内存、信号量、套接字。

 

共同点

 

 由上面的分析能够看出两个操做系统共有的且用的较多的进程间通讯机制有:管道、消息、共享内存和套接字。简介以下:

 

  管道(Pipe)及有名管道(named pipe):管道可用于具备亲缘关系进程间的通讯,有名管道克服了管道没有名字的限制,所以,除具备管道所具备的功能外,它还容许无亲缘关系进程间的通讯。

 

   信号或者消息(Signal):信号是比较复杂的通讯方式,用于通知接受进程有某种事件发生,除了用于进程间通讯外,进程还能够发送信号给进程自己。

 

   共享内存:使得多个进程能够访问同一块内存空间,是最快的可用IPC形式。是针对其余通讯机制运行效率较低而设计的。每每与其它通讯机制,如信号量结合使用,来达到进程间的同步及互斥。

 

   套接口(Socket):更为通常的进程间通讯机制,可用于不一样机器之间的进程间通讯。

 

 

 

总结

 

消息队列是消息的连接表,消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点;而信号量主要做为进程间以及同一进程不一样线程之间的同步手段。

 

   我的认为:管道、剪贴板、共享内存都是基于共享内存的方式。而消息、消息队列和套接字的都是基于发消息的机制,只是看是在同一个机器上发仍是在网络中发消息而已(套接字能够看作在网络中发送消息)。至于RPC、COM、OLE、DDE主要是在客户端和服务器端生成一个统一的接口。也就是说这几个通讯手段其实就至关于网络上的协议。在同一层通讯的协议无论下一层,好像这两层直接创建了联系。这个基本的思想是在本地创建相似存根代码的代码,而在远程创建相似桩代码的代码来进行链接。

 

   这上面的通讯方式中,剪切板和匿名管道只能实现同一机器上两个进程间的通讯,而信号量、消息、消息队列和共享内存也只能在同一台机器上的多个进程间通讯;可是命名管道、邮件槽和套接字不只能够实现同一机器上的两个进程的通讯,还能够实现跨网络的进程间通讯;另外,油槽和套接字能够实现一对多的通讯,而命名管道只能是点对点的单一通讯,但油槽的缺点是数据量较小,一般都是在424字节如下,若是数据量较大,则能够采用命名管道和套接字的方式来完成。综上:在跨网络通讯中套接字无疑是最优秀的通讯方式,这或许是伯克利开发套接字来进行网络通讯的初衷吧(传统通讯方式很差用)。

 

参考:

1:http://blog.sina.com.cn/s/blog_6002b97001013wec.html

2:http://blog.csdn.net/liuzhanchen1987/article/details/7452910

相关文章
相关标签/搜索