Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1676454
  • 博文数量: 585
  • 博客积分: 14610
  • 博客等级: 上将
  • 技术积分: 7402
  • 用 户 组: 普通用户
  • 注册时间: 2008-05-15 10:52
文章存档

2013年(5)

2012年(214)

2011年(56)

2010年(66)

2009年(44)

2008年(200)

分类: C/C++

2012-04-29 04:52:51

进程间通讯实现方法    


 进程通常被定义为一个正在运行的程序的实例,它由两个部分组成:
       一个是操作系统用来管理进程的内核对象。内核对象也是系统用来存放关于进程的统计信息的地方
      另一个是地址空间,它包含所有的可执行模块或DLL模块的代码和数据。它还包含动态分配的空间。如线程堆栈和堆分配空间。每个进程被赋予它自己的虚拟地址空间,当进程中的一个线程正在运行时,该线程可以访问只属于它的进程的内存。属于其它进程的内存则是隐藏的,并不能被正在运行的线程访问。
   为了能在两个进程之间进行通讯,由以下几种方法可供参考:

1。剪贴板(Clipped Board)实质是Win32 API中一组用来传输数据的函数和消息,为Windows应用程序之间进行数据共享提供了一个中介,Windows已建立的剪切(复制)-粘贴的机制为不同应用程序之间共享不同格式数据提供了一条捷径。当用户在应用程序中执行剪切或复制操作时,应用程序把选取的数据用一种或多种格式放在剪贴板上。然后任何其它应用程序都可以从剪贴板上拾取数据,从给定格式中选择适合自己的格式。

2。窗口消息 标准的Windows消息以及专用的WM_COPYDATA消息 SENDMESSAGE()接收端必须有一个窗口

3。使用共享内存方式(Shared Memory)
   a.设定一块共享内存区域           
     HANDLE CreateFileMapping(HANDLE,LPSECURITY_ATTRIBUTES, DWORD, DWORD, DWORD,  LPCSTR) 
     产生一个file-mapping核心对象
     LPVOID MapViewOfFile(
         HANDLE hFileMappingObject,
         DWORD  dwDesiredAcess,
         DWORD  dwFileOffsetHigh,
         DWORD  dwFileOffsetLow,
         DWORD  dwNumberOfBytesToMap
     );
    得到共享内存的指针
   b.找出共享内存
    决定这块内存要以点对点(peer to peer)的形式呈现
        每个进程都必须有相同的能力,产生共享内存并将它初始化。每个进程
        都应该调用CreateFileMapping(),然后调用GetLastError().如果传回的
        错误代码是ERROR_ALREADY_EXISTS,那么进程就可以假设这一共享内存区         域已经被别的进程打开并初始化了,否则该进程就可以合理的认为自己 排在第          一位,并接下来将共享内存初始化。
    还是要使用client/server架构中
       只有server进程才应该产生并初始化共享内存。所有的进程都应该使用

HANDLE OpenFileMapping(DWORD dwDesiredAccess,
                                   BOOL bInheritHandle,
                                   LPCTSTR lpName);
        再调用MapViewOfFile(),取得共享内存的指针
   c.同步处理(Mutex)
   d.清理(Cleaning up) BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);
                        CloseHandle()

4。动态数据交换(DDE)通过维护全局分配内存使的应用程序间传递.
     动态数据交换(DDE)是使用共享内存在应用程序之间进行数据交换的一种进程间通信形式。应用程序可以使用DDE进行一次性数据传输,也可以当出现新数据时,通过发送更新值在应用程序间动态交换数据。
  DDE和剪贴板一样既支持标准数据格式(如文本、位图等),又可以支持自己定义的数据格式。但它们的数据传输机制却不同,一个明显区别是剪贴板操作几乎总是用作对用户指定操作的一次性应答-如从菜单中选择Paste命令。尽管DDE也可以由用户启动,但它继续发挥作用一般不必用户进一步干预。DDE有三种数据交换方式:
  (1) 冷链:数据交换是一次性数据传输,与剪贴板相同。
  (2) 温链:当数据交换时服务器通知客户,然后客户必须请求新的数据。
  (3) 热链:当数据交换时服务器自动给客户发送数据。
  DDE交换可以发生在单机或网络中不同计算机的应用程序之间。开发者还可以定义定制的DDE数据格式进行应用程序之间特别目的IPC,它们有更紧密耦合的通信要求。大多数基于Windows的应用程序都支持DDE。

5。消息管道(Message Pipe)
   用于设置应用程序间的一条永久通讯通道,通过该通道可以象自己的应用程序
   访问一个平面文件一样读写数据。
   匿名管道(Anonymous Pipes)
       单向流动,并且只能够在同一电脑上的各个进程之间流动。
   命名管道(Named Pipes)
       双向,跨网络,任何进程都可以轻易的抓住,放进管道的数据有固定的格        式,而使用ReadFile()只能读取该大小的倍数。
       可以被使用于I/O Completion Ports

6   邮件槽(Mailslots)
    广播式通信,在32系统中提供的新方法,可以在不同主机间交换数据。邮槽(Mailslots)提供进程间单向通信能力,任何进程都能建立邮槽成为邮槽服务器。其它进程,称为邮槽客户,可以通过邮槽的名字给邮槽服务器进程发送消息。进来的消息一直放在邮槽中,直到服务器进程读取它为止。
    邮槽与命名管道相似,不过它传输数据是通过不可靠的数据报(如TCP/IP协议中的UDP包)完成的,一旦网络发生错误则无法保证消息正确地接收,而命名管道传输数据则是建立在可靠连接基础上的。不过邮槽有简化的编程接口和给指定网络区域内的所有计算机广播消息的能力,所以邮槽不失为应用程序发送和接收消息的另一种选择。


7。Windows套接字(Windows Socket)
   它具备消息管道所有的功能,但遵守一套通信标准使的不同操作系统之上的应    用程序之间可以互相通信。

8。动态连接库
     Win32动态连接库(DLL)中的全局数据可以被调用DLL的所有进程共享,这就又给进程间通信开辟了一条新的途径,当然访问时要注意同步问题。需要将全局数据放入共享代码段里面。在 Win32 环境中,每个进程都复制了自己的读/写全局变量。如果想要与其它进程共享内存,必须使用内存映射文件或者声明一个共享数据段。DLL 模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。 在加载 DLL 模块时将进程函数调用与 DLL 文件的导出函数相匹配。 操作系统对 DLL 的操作仅仅是把 DLL 映射到需要它的进程的虚拟地址空间里去。DLL 函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
  虽然可以通过DLL进行进程间数据共享,但从数据安全的角度考虑,我们并不提倡这种方法,使用带有访问权限控制的共享内存的方法更好一些。

9。RPC:远程过程调用,很少使用,因其与UNIX的RPC不兼容。
     Win32 API提供的远程过程调用(RPC)使应用程序可以使用远程调用函数,这使在网络上用RPC进行进程通信就像函数调用那样简单。RPC既可以在单机不同进程间使用也可以在网络中使用。
  由于Win32 API提供的RPC服从OSF-DCE(Open Software Foundation Distributed Computing Environment)标准。所以通过Win32 API编写的RPC应用程序能与其它操作系统上支持DEC的RPC应用程序通信。使用RPC开发者可以建立高性能、紧密耦合的分布式应用程序。

10。串行/并行通信(Serial/Parallel Communication)
   它允许应用程序通过串行或并行端口与其他的应用程序通信。

11。COM/DCOM 
     通过COM系统的代理存根方式进行进程间数据交换,但只能够表现在对接口     函数的调用时传送数据,通过DCOM可以在不同主机间传送数据。

阅读(613) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~