zoukankan      html  css  js  c++  java
  • windows下进程间通信与线程间通信

    进程间通信:

    1.文件映射(Memory-Mapped Files)

    文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待。因此,进程不必使用文件I/O操作, 
    只需简单的指针操作就可读取和修改文件的内容。

    Win32 API允许多个进程访问同一文件映射对象,各个进程在它自己的地址空间里接收内存的指针通过使用这些指针,不同进程就可以读或修改文件的内容, 实现对文件中数据的共享

    文件映射是在多个进程间共享数据的非常有效方法,有较好的安全性。但文件映射只能用于本地机器的进程之间,不能用于网络中 ,而开发者还必须控制进程间的同步。

    关于文件映射见:

    2. 共享内存 
    Win32 API中共享内存(Shared Memory)实际就是文件映射的一种特殊情况。进程在创建文件映射对象时用0xFFFFFFFF来代替 文件句柄(HANDLE), 
    就表示了对应的文件映射对象是从操作系统页面文件访问内存,其它进程打开该文件映射对象就可以访问该内存块。由于共享内存是用 文件映射实现的, 所以它也有较好的安全性,也只能运行于同一计算机上的进程之间

    2.3 匿名管道 
    管道(Pipe)是一种具有两个端点的通信通道:有一端句柄的进程可以和有另一端句柄的进程通信。管道可以是单向-一端是只读的,另一端点是只写的; 也可以是双向的一管道的两端点既可读也可写
    匿名管道(Anonymous Pipe)是 在父进程和子进程之间,或同一父进程的两个子进程之间传输数据的无名字的单向管道。通常由父进程创建管 道, 
    然后由要通信的子进程继承通道的读端点句柄或写 端点句柄,然后实现通信。父进程还可以建立两个或更多个继承匿名管道读和写句柄的子进程。 
    这些子进程 可以使用管道直接通信,不需要通过父进程。 
    匿名管道是单机上实现子进程标准I/O重定向的有效方法,它不能在网上使用,也不能用于两个不相关的进程之间。 
    2.4 命名管道 
    命名管道(Named Pipe)是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是命名管道可以在不相关的进程之间和不 同计算机之间使用 
    服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。 
    命名管道提供了相对简单的编程接口,使通过网络传输数据并不比同一计算机上两进程之间通信更困难,不过如果要同时和多个进程通信它就力不从心了。 
    2.5 邮件槽 
    邮件槽(Mailslots)提 供进程间单向通信能力,任何进程都能建立邮件槽成为邮件槽服务器。其它进程,称为邮件槽客户,可以通过邮件槽的名字给 
    邮件槽服务器进程发送消息。进来的消 息一直放在邮件槽中,直到服务器进程读取它为止。一个进程既可以是邮件槽服务器也可以是邮件槽客户, 
    因此可建立多个 邮件槽实现进程间的双向通信。 
    通过邮件槽可以给本地计算机上的邮件槽、其它计算机上的邮件槽或指定网络区域中所有计算机上有同样名字的邮件槽发送消息。 
    广播通信的消息长度不能超过400字节,非广播消息的长度则受邮件槽服务器指定的最大消息长度的限制。 
    邮件槽与命名管道相似,不过它传输数据是通过不可靠的数据报(如TCP/IP协议中的UDP包)完成的,一旦网络发生错误则无法保证消息正确地接收, 
    而 命名管道传输数据则是建立在可靠连接基础上的。不过邮件槽有简化的编程接口和给指定网络区域内的所有计算机广播消息的能力, 
    所以邮件槽不失为应用程序发送 和接收消息的另一种选择。 
    2.6 剪贴板 
       剪贴板(Clipped Board)实质是Win32 API中一组用来传输数据的函数和消息,为Windows应用程序之间进行数据共享提供了一个中介, 
    Windows已建立的剪切(复制)-粘贴的机制为不同应用程序之间共享不同格式数据提供了一条捷径。当用户在应用程序中执行剪切或复制操作时, 
    应 用程序把选取的数据用一种或多种格式放在剪贴板上。然后任何其它应用程序都可以从剪贴板上拾取数据,从给定格式中选择适合自己的格式。 
    剪贴板 是一个非常松散的交换媒介,可以支持任何数据格式,每一格式由一无符号整数标识,对标准(预定义)剪贴板格式,该值是Win32 API定义的常量; 
    对非 标准格式可以使用Register Clipboard Format函数注册为新的剪贴板格式。利用剪贴板进行交换的数据只需在数据格式上一致或都可以 
    转化为某种格式就行。但剪贴板只能在基于Windows的程序中使用,不能在网络上使用。 

    2.7 Sockets 
    Windows Sockets规范是以U.C.Berkeley大学BSD UNIX中流行的Socket接口为范例定义的一套Windows下的网 络编程接口。除了Berkeley Socket原有的库函数以外 
    ,还扩展了一组针对Windows的函数,使程序员可以充分利用Windows的消息机 制进行编程。 
    现在通过Sockets实现进程通信的网络应用越来越多,这主要的原因是Sockets的跨平台性要比其它IPC机制好得多,另 外WinSock 2.0不仅支持TCP/IP协议, 
    而且还支持其它协议(如IPX)。Sockets的唯一缺点是它支持的是底层通信操作,这使得在单机 的进程间进行简单数据传递不太方便, 
    这时使用下面将介绍的WM_COPYDATA消息将更合适些。 
    2.8.WM_COPYDATA消息 
    WM_COPYDATA是一种非常强大却鲜为人知的消息。当一个应用向另一个应用传送数据时,发送方只需使用调用SendMessage函数, 
    参数是目 的窗口的句柄、传递数据的起始地址、WM_COPYDATA消息。接收方只需像处理其它消息那样处理WM_COPY DATA消息,这样收发双方就实现了 数据共享。 
    WM_COPYDATA是一种非常简单的方法,它在底层实际上是通过文件映射来实现的。

    线程间通信方式

    1、线程间的通信方式
    • 使用全局变量
      主要由于多个线程可能更改全局变量,因此全局变量最好声明为violate
    • 使用消息实现通信
      在Windows程序设计中,每一个线程都可以拥有自己的消息队列(UI线程默认自带消息队列和消息循环,工作线程需要手动实现消息循环),因此可以采用消息进行线程间通信sendMessage,postMessage。
      1)定义消息#define WM_THREAD_SENDMSG=WM_USER+20;  
      2)添加消息函数声明afx_msg int OnTSendmsg(); 
      3)添加消息映射ON_MESSAGE(WM_THREAD_SENDMSG,OnTSM) 
      4)添加OnTSM()的实现函数;
      5)在线程函数中添加PostMessage消息Post函数
    • 使用事件CEvent类实现线程间通信
      Event对象有两种状态:有信号和无信号,线程可以监视处于有信号状态的事件,以便在适当的时候执行对事件的操作。
      1)创建一个CEvent类的对象:CEvent threadStart;它默认处在未通信状态; 
      2)threadStart.SetEvent();使其处于通信状态; 
      3)调用WaitForSingleObject()来监视CEvent对象
  • 相关阅读:
    内存泄露检测工具之DMalloc
    五年后你在何方
    程序员技术练级攻略
    Windows编程革命简史
    su的时候密码认证失败的解决方法
    ruby 元编程 meta programming
    内存对齐分配策略(含位域模式)
    Ruby 之 Block, Proc, Lambda 联系区别,转载
    c++异常处理机制示例及讲解
    ruby 常见问题集 1 不断更新中
  • 原文地址:https://www.cnblogs.com/curo0119/p/8623391.html
Copyright © 2011-2022 走看看