进程间通信-Windows

来源:互联网 发布:美国宝宝的好处知乎 编辑:程序博客网 时间:2024/06/06 19:17

参考博客:http://blog.csdn.net/bresponse/article/details/7085774  进程间通信方式总结,

参考博客:http://www.cnblogs.com/zibility/p/5657308.html  几种Windows进程通信+代码!

参考博客:http://blog.csdn.net/u013080921/article/details/44808949  Windows和Linux进程间通信区别 !!!

参考博客:http://www.cnblogs.com/sooner/archive/2013/07/15/3191903.html Windows与Linux下进程间通信技术比较

windows的进程间的通信方式:

1、管道:匿名管道和命名管道 2、邮件槽(mailslot)(点对点消息队列)3.文件映射和共享内存(是文件映射的一种特殊情况)4.socket;5.消息:WM_COPYDATA6.剪贴板;7.动态数据交换;8.对象链接与嵌入;9.远程过程调用;10.动态链接库;

 linux进程间通信的方式有:1.管道  2.消息队列 3.共享内存 4.信号5.信号量 6.套接字 

 windows和linux共有的进程间通信方式:1. 管道 2. 邮槽(Linux中叫做消息队列)3. 共享内存 4. 消息(linux中叫做信号) 5.socket

1、管道(Pipe)
一个进程往管道里写数据,另一个进程从管道里取数据。管道又可以分为匿名管道,匿名管道只能在父、子进程之间通讯。还有一种命名管道(named pipes),Linux下叫做FIFO,命名管道可以在任意进程之间通讯。

2、油槽(Slot)
Linux下叫做消息队列(Message)。就像我们日常通过邮局寄送信件。一个进程寄送,另一个进程接收。

3、共享内存(Shared Memory)
进程之间通过共享一块内存的方式来交换数据。

4、消息(Message)
Linux下叫做信号(Signal)。Windows是消息驱动的,进程可以调用WIN32 API函数SendMessage或者PostMessage向另一个进程发送消息,Windows系统也可以向进程发送消息。
Linux下可以通过kill、raise、alarm、pause这些信号处理系统调用来实现。

5、Socket
通常我们使用socket来进行网络通讯,一方作为客户机,另一方作为服务器。同样的,socket也可以作为进程之间通讯的一种方式

windows的进程间的通信方式:

1、管道:

1.1、匿名管道管道(Pipe)是一种具有两个端点的通信通道:有一端句柄的进程可以和有另一端句柄的进程通信。管道可以是单向-一端是只读的,另一端点是只写的;也可以是双向的一管道的两端点既可读也可写。
匿名管道(Anonymous Pipe),是 在父进程和子进程之间,或同一父进程的两个子进程之间传输数据的无名字的单向管道。通常由父进程创建管道,然后由要通信的子进程继承通道的读端点句柄或写 端点句柄,然后实现通信。父进程还可以建立两个或更多个继承匿名管道读和写句柄的子进程。这些子进程可以使用管道直接通信,不需要通过父进程。
匿名管道是单机上实现子进程标准I/O重定向的有效方法,它不能在网上使用,也不能用于两个不相关的进程之间。
1.2、命名管道,命 名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是命名管道可以在不相关的进程之间和不同计算机之间使用,服务器 建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。

命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。

2、 邮件槽
邮件槽(Mailslots)提供进程间单向通信能力,任何进程都能建立邮件槽成为邮件槽服务器。其它进程,称为邮件槽客户,可以通过邮件槽的名字给邮件槽服务器进程发送消息。进来的消息一直放在邮件槽中,直到服务器进程读取它为止。一个进程既可以是邮件槽服务器也可以是邮件槽客户,因此可建立多个邮件槽实现进程间的双向通信。通过邮件槽可以给本地计算机上的邮件槽、其它计算机上的邮件槽或指定网络区域中所有计算机上有同样名字的邮件槽发送消息。广播通信的消息长度不能超过400字节,非广播消息的长度则受邮件槽服务器指定的最大消息长度的限制。
邮 件槽与命名管道相似,不过它传输数据是通过不可靠的数据报(如TCP/IP协议中的UDP包)完成的,一旦网络发生错误则无法保证消息正确地接收,而命名 管道传输数据则是建立在可靠连接基础上的。不过邮件槽有简化的编程接口和给指定网络区域内的所有计算机广播消息的能力,所以邮件槽不失为应用程序发送和接 收消息的另一种选择。

3、文件映射---点击打开链接--本人汇总文件映射信息
3.1、文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待。因此,进程不必使用文件I/O操作,只需简单的指针操作就可读取和修改文件的内容。Win32 API允许多个进程访问同一文件映射对象,各个进程在它自己的地址空间里接收内存的指针。通过使用这些指针,不同进程就可以读或修改文件的内容,实现了对文件中数据的共享。
应用程序有三种方法来使多个进程共享一个文件映射对象。
实现多进程共享一个文件映射的三种方法:
(1)继承:第一个进程建立文件映射对象,它的子进程继承该对象的句柄。
(2)命名文件映射:第一个进程在建立文件映射对象时可以给该对象指定一个名字(可与文件名不同)。第二个进程可通过这个名字打开此文件映射对象。另外,第一个进程也可以通过一些其它IPC机制(有名管道、邮件槽等)把名字传给第二个进程。
(3)句柄复制:第一个进程建立文件映射对象,然后通过其它IPC机制(有名管道、邮件槽等)把对象句柄传递给第二个进程。第二个进程复制该句柄就取得对该文件映射对象的访问权限。
文件映射是在多个进程间共享数据的非常有效方法,有较好的安全性。但文件映射只能用于本地机器的进程之间,不能用于网络中,而开发者还必须控制进程间的同步。
3.2 、共享内存
Win32 API中共享内存(Shared Memory)实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用0xFFFFFFFF来代替文件句柄(HANDLE),就表示了对应的文件映 射对象是从操作系统页面文件访问内存,其它进程打开该文件映射对象就可以访问该内存块。由于共享内存是用文件映射实现的,所以它也有较好的安全性,也只能 运行于同一计算机上的进程之间。
4、Socket通信--点击打开链接--本人汇总Socket通信

通 过Sockets实现进程通信的网络应用越来越多,这主要的原因是Sockets的跨平台性要比其它IPC机制好得多,另外WinSock 2.0不仅支持TCP/IP协议,而且还支持其它协议(如IPX)。Sockets的唯一缺点是它支持的是底层通信操作,这使得在单机的进程间进行简单数 据传递不太方便,这时使用下面将介绍的WM_COPYDATA消息将更合适些。

5、WM_COPYDATA消息实现进程间通信--点击打开链接--它的底层是通过文件映射来实现的,缺点是灵活性不高,只用于Windows平台的单机环境

该消息只能由SendMessage()发送,而不能使用PostMessage()。因为系统必须管理用以传递数据的缓冲区的生命期,如果使用了PostMessage(),数据缓冲区会在接收方(线程)有机会处理该数据之前,就被系统清除和回收。如果传入的接收窗口句柄无效或者当接收方进程意外终止时,SendMessage()会立即返回,发送方不会陷入一个无穷等待的状态中。

消息作用:    在进程间共享数据(内部通过创建内存映射文件)消息介绍:需要用到的数据结构/类型:typedef struct tagCOPYDATASTRUCT {    ULONG_PTR dwData;  // 保存一个数值, 可以用来作标志等
    DWORD cbData;         //待发送的数据的长度    PVOID lpData;         //待发送的数据的起始地址(可以为NULL)} COPYDATASTRUCT, *PCOPYDATASTRUCT;
LRESULT WINAPI SendMessage(   //发送消息的函数,此处说明发送WM_COPYDATA的参数  _In_  HWND hWnd,   //接收数据的窗口的句柄  _In_  UINT Msg,    //WM_COPYDATA  _In_  WPARAM wParam,//传送该数据的窗口句柄(NULL也无所谓)  _In_  LPARAM lParam //COPYDATASTRUCT类型变量的地址);
//获得窗口指针的函数: HWND hWnd=::FindWindow(NULL(注册信息),_T("Process B")(窗口标题));

6、 剪贴板
  剪贴板(Clipped Board)实质是Win32 API中一组用来传输数据的函数和消息,为Windows应用程序之间进行数据共享提供了一个中介,Windows已建立的剪切(复制)-粘贴的机制为不同应用程序之间共享不同格式数据提供了一条捷径。当用户在应用程序中执行剪切或复制操作时,应用程序把选取的数据用一种或多种格式放在剪贴板上。然后任何其它应用程序都可以从剪贴板上拾取数据,从给定格式中选择适合自己的格式。
  剪贴板是一个非常松散的交换媒介,可以支持任何数据格式,每一格式由一无符号整数标识,对标准(预定义)剪贴板格式,该值是Win32 API定义的常量;对非标准格式可以使用Register Clipboard Format函数注册为新的剪贴板格式。利用剪贴板进行交换的数据只需在数据格式上一致或都可以转化为某种格式就行。但剪贴板只能在基于Windows的程序中使用,不能在网络上使用。
7、 动态数据交换
  动态数据交换(DDE)是使用共享内存在应用程序之间进行数据交换的一种进程间通信形式。应用程序可以使用DDE进行一次性数据传输,也可以当出现新数据时,通过发送更新值在应用程序间动态交换数据。
  DDE和剪贴板一样既支持标准数据格式(如文本、位图等),又可以支持自己定义的数据格式。但它们的数据传输机制却不同,一个明显区别是剪贴板操作几乎总是用作对用户指定操作的一次性应答-如从菜单中选择Paste命令。尽管DDE也可以由用户启动,但它继续发挥作用一般不必用户进一步干预。DDE有三种数据交换方式:
  (1) 冷链:数据交换是一次性数据传输,与剪贴板相同。
  (2) 温链:当数据交换时服务器通知客户,然后客户必须请求新的数据。
  (3) 热链:当数据交换时服务器自动给客户发送数据。
  DDE交换可以发生在单机或网络中不同计算机的应用程序之间。开发者还可以定义定制的DDE数据格式进行应用程序之间特别目的IPC,它们有更紧密耦合的通信要求。大多数基于Windows的应用程序都支持DDE。
8、 对象连接与嵌入
  应用程序利用对象连接与嵌入(OLE)技术管理复合文档(由多种数据格式组成的文档),OLE提供使某应用程序更容易调用其它应用程序进行数据编辑的服务。例如,OLE支持的字处理器可以嵌套电子表格,当用户要编辑电子表格时OLE库可自动启动电子表格编辑器。当用户退出电子表格编辑器时,该表格已在原始字处理器文档中得到更新。在这里电子表格编辑器变成了字处理器的扩展,而如果使用DDE,用户要显式地启动电子表格编辑器。
  同DDE技术相同,大多数基于Windows的应用程序都支持OLE技术。
9 、动态连接库
  Win32动态连接库(DLL)中的全局数据可以被调用DLL的所有进程共享,这就又给进程间通信开辟了一条新的途径,当然访问时要注意同步问题。
  虽然可以通过DLL进行进程间数据共享,但从数据安全的角度考虑,我们并不提倡这种方法,使用带有访问权限控制的共享内存的方法更好一些。
10、 远程过程调用
  Win32 API提供的远程过程调用(RPC)使应用程序可以使用远程调用函数,这使在网络上用RPC进行进程通信就像函数调用那样简单。RPC既可以在单机不同进程间使用也可以在网络中使用。
  由于Win32 API提供的RPC服从OSF-DCE(Open Software Foundation Distributed Computing Environment)标准。所以通过Win32 API编写的RPC应用程序能与其它操作系统上支持DEC的RPC应用程序通信。使用RPC开发者可以建立高性能、紧密耦合的分布式应用程序。
11、NetBios函数
  Win32 API提供NetBios函数用于处理低级网络控制,这主要是为IBM NetBios系统编写与Windows的接口。除非那些有特殊低级网络功能要求的应用程序,其它应用程序最好不要使用NetBios函数来进行进程间通信。

 Linux进程间通信和Windows对比

介绍完了Windows,介绍linux就相对轻松一些了,虽然WindowsLinux形同水火,打的不可开交,但实际上说白了,它们并不是两个完全不同的东东,在很多的地方都相似,进程间通信也不例外。

Linux的进程间通信主要有管道、命名管道、消息队列、共享内存、信号量,其中信号量Semaphore其实是为了同步用的,因此我这里就放到下一篇关于同步的博文中去分析。另外,很多人将信号signal也作为进程间通信,但我认为信号更像是为了同步而设计的,因此也放到下一篇博文中去分析。

1.2.1   管道

Linux的管道和Windows的管道是一样的,这里就不详细介绍了。

需要注意的是Linux多了一个叫做“流管道”的东东,除了流管道是全双工(也就是双向)外,流管道其它都和管道一样。

1.2.2   命名管道

Linux的命名管道和Windows的命名管道差异就比较大了,主要对比如下:

对比点

Linux

Windows

备注

消息格式

字节流

二进制

Windows更牛

工作模式

半双工

全双工

Windows更牛

访问模式

只能在一台机器上

可以跨网络

Windows更牛

 

1.2.3   消息队列

这个是Linux特有的进程通信方式,我感觉它有点像邮槽,都能够实现一对多。不过消息队列和邮槽的方向正好相反:消息队列是一堆进程向一个进程发,邮槽是一个进程向一堆进程发

消息队列还有一个牛B的特性就是消息队列的消息可以分优先级,进程不一定非要取第一个消息,也可以取指定消息优先级的消息。因此这个特性又可用于多对多通信,即:不同的收方指定不同的优先级。当然实际应用中应该没人会这么用,直接创建多个消息队列是最方便、最简单、效率最高的方法。

1.2.4   共享内存

Linux的共享内存机制和Windows本质上是一样的,即都是利用了内存映射的功能。不过Linux将“内存映射到内存”包装成了“共享内存”,而不像Windows,在使用的时候通过指定不同的参数来区分是“内存映射到文件”还是“共享内存”,所以各位大侠可能在网上有时能够看到有人将“内存映射”和“共享内存”都说是Linux进程间通信的方式,原因就在这里。

1.3        OS间进程通信

前面分别介绍了WindowsLinux进程间通信,看到这里,你肯定会有疑问:什么?还有OS进程间通信?不同OS之间的进程是不可能通信的!

是的,从操作系统层面来说,Windows的进程和Linux的进程当然是不能通信的,但如果从网络层面来说,两台机器总是要通信的吧?不可能Windows只能和Windows通信,Linux只和Linux通信吧?

说到这里估计你已经恍然大悟了:不就是Socket通信么?


原创粉丝点击