Windows核心编程之进程间通信

2023-05-16

1 进程与进程通信

  进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码、数据以及它可利用的系统资源(如文件、管道等)组成。多进程/多线程是Windows操作系统的一个基本特征。Microsoft Win32应用编程接口(Application Programming Interface, API)提供了大量支持应用程序间数据共享和交换的机制,这些机制行使的活动称为进程间通信(InterProcess Communication, IPC),进程通信就是指不同进程间进行数据共享和数据交换。
  正因为使用Win32 API进行进程通信方式有多种,如何选择恰当的通信方式就成为应用开发中的一个重要问题,下面本文将对Win32中进程通信的几种方法加以分析和比较。

2 进程通信方法

2.1 文件映射
  文件映射(Memory-Mapped Files)能使进程把文件内容当作进程地址区间一块内存那样来对待。因此,进程不必使用文件I/O操作,只需简单的指针操作就可读取和修改文件的内容。
  Win32 API允许多个进程访问同一文件映射对象,各个进程在它自己的地址空间里接收内存的指针。通过使用这些指针,不同进程就可以读或修改文件的内容,实现了对文件中数据的共享。
  应用程序有三种方法来使多个进程共享一个文件映射对象。
  (1)继承:第一个进程建立文件映射对象,它的子进程继承该对象的句柄。
  (2)命名文件映射:第一个进程在建立文件映射对象时可以给该对象指定一个名字(可与文件名不同)。第二个进程可通过这个名字打开此文件映射对象。另外,第一个进程也可以通过一些其它IPC机制(有名管道、邮件槽等)把名字传给第二个进程。
  (3)句柄复制:第一个进程建立文件映射对象,然后通过其它IPC机制(有名管道、邮件槽等)把对象句柄传递给第二个进程。第二个进程复制该句柄就取得对该文件映射对象的访问权限。
  文件映射是在多个进程间共享数据的非常有效方法,有较好的安全性。但文件映射只能用于本地机器的进程之间,不能用于网络中,而开发者还必须控制进程间的同步。
2.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 动态数据交换
  动态数据交换(DDE)是使用共享内存在应用程序之间进行数据交换的一种进程间通信形式。应用程序可以使用DDE进行一次性数据传输,也可以当出现新数据时,通过发送更新值在应用程序间动态交换数据。
  DDE和剪贴板一样既支持标准数据格式(如文本、位图等),又可以支持自己定义的数据格式。但它们的数据传输机制却不同,一个明显区别是剪贴板操作几乎总是用作对用户指定操作的一次性应答-如从菜单中选择Paste命令。尽管DDE也可以由用户启动,但它继续发挥作用一般不必用户进一步干预。DDE有三种数据交换方式:
  (1) 冷链:数据交换是一次性数据传输,与剪贴板相同。
  (2) 温链:当数据交换时服务器通知客户,然后客户必须请求新的数据。
  (3) 热链:当数据交换时服务器自动给客户发送数据。
  DDE交换可以发生在单机或网络中不同计算机的应用程序之间。开发者还可以定义定制的DDE数据格式进行应用程序之间特别目的IPC,它们有更紧密耦合的通信要求。大多数基于Windows的应用程序都支持DDE。
2.8 对象连接与嵌入
  应用程序利用对象连接与嵌入(OLE)技术管理复合文档(由多种数据格式组成的文档),OLE提供使某应用程序更容易调用其它应用程序进行数据编辑的服务。例如,OLE支持的字处理器可以嵌套电子表格,当用户要编辑电子表格时OLE库可自动启动电子表格编辑器。当用户退出电子表格编辑器时,该表格已在原始字处理器文档中得到更新。在这里电子表格编辑器变成了字处理器的扩展,而如果使用DDE,用户要显式地启动电子表格编辑器。
  同DDE技术相同,大多数基于Windows的应用程序都支持OLE技术。
2.9 动态连接库
  Win32动态连接库(DLL)中的全局数据可以被调用DLL的所有进程共享,这就又给进程间通信开辟了一条新的途径,当然访问时要注意同步问题。
  虽然可以通过DLL进行进程间数据共享,但从数据安全的角度考虑,我们并不提倡这种方法,使用带有访问权限控制的共享内存的方法更好一些。
2.10 远程过程调用
  Win32 API提供的远程过程调用(RPC)使应用程序可以使用远程调用函数,这使在网络上用RPC进行进程通信就像函数调用那样简单。RPC既可以在单机不同进程间使用也可以在网络中使用。
  由于Win32 API提供的RPC服从OSF-DCE(Open Software Foundation Distributed Computing Environment)标准。所以通过Win32 API编写的RPC应用程序能与其它操作系统上支持DEC的RPC应用程序通信。使用RPC开发者可以建立高性能、紧密耦合的分布式应用程序。
2.11 NetBios函数
  Win32 API提供NetBios函数用于处理低级网络控制,这主要是为IBM NetBios系统编写与Windows的接口。除非那些有特殊低级网络功能要求的应用程序,其它应用程序最好不要使用NetBios函数来进行进程间通信。
2.12 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.13 WM_COPYDATA消息
  WM_COPYDATA是一种非常强大却鲜为人知的消息。当一个应用向另一个应用传送数据时,发送方只需使用调用SendMessage函数,参数是目的窗口的句柄、传递数据的起始地址、WM_COPYDATA消息。接收方只需像处理其它消息那样处理WM_COPY DATA消息,这样收发双方就实现了数据共享。
  WM_COPYDATA是一种非常简单的方法,它在底层实际上是通过文件映射来实现的。它的缺点是灵活性不高,并且它只能用于Windows平台的单机环境下。

3 结束语

  Win32 API为应用程序实现进程间通信提供了如此多种选择方案,那么开发者如何进行选择呢?通常在决定使用哪种IPC方法之前应考虑以下一些问题:

  (1)应用程序是在网络环境下还是在单机环境下工作。

       (2)应用程序用于何种目的,对进程间通信有何种要求。

管道:速度慢,容量有限,只有父子进程能通讯。

FIFO:任何进程间都能通讯,但速度慢。

消息队列:容量受到系统限制,且要注意第一次读的时候,要考虑上一次没有读完数据的问题。

信号量:不能传递复杂消息,只能用来同步。

共享内存区:能够很容易控制容量,速度快,但要保持同步,比如一个进程在写的时候,另一个进程要注                         意读写的问题,相当于线程中的线程安全,当然,共享内存区同样可以用作线程间通讯,不                         过没这个必要,线程间本来就已经共享了同一进程内的一块内存。


本文参考文章:

http://blog.csdn.net/weijinqian0/article/details/52334102

https://www.cnblogs.com/findumars/p/6329593.html

https://blog.codingnow.com/2005/10/interprocess_communications.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows核心编程之进程间通信 的相关文章

  • Windows 10:任务栏中的图标大小错误

    从 Windows 10 开始 任务栏中的图标大小似乎为 24x24px 如果 Windows 选择图标文件中的 24px 版本进行显示 那么这不会有问题 但它选择了 32px 版本并将其缩小 这会导致丑陋的伪像 尤其是当你的图标中有直线时
  • msvcrt.getch() 每次都会检测到空格

    我正在编写一个简单的Python代码 它应该检测我的击键 但由于某种原因 在每次击键后检测空格 代码 import msvcrt print press escape to quit text while 1 char msvcrt get
  • 为进程设置环境变量

    环境变量的概念是什么 在 C 程序中 我需要调用可执行文件 该可执行文件将调用驻留在同一文件夹中的一些其他可执行文件 可执行文件依赖于两个环境变量 PATH 和 RAYPATH 的正确设置 我尝试了以下两件事 我创建了一个进程并在 Star
  • QWinTaskbarProgress 不会显示

    我使用的是windows7和Qt5 3 0 我在 MainWindow 的构造函数中添加了以下内容 但任务栏上没有显示任何内容 我错过了什么 QWinTaskbarProgress pTaskbarProgress new QWinTask
  • 在 SYSTEMTIME 上执行算术

    我有一个以 SYSTEMTIME 表示的时间值 我想从中添加 减去 1 小时并获取新获得的 SYSTEMTIME 我希望转换应该处理加法 减法或月份更改或 e1 年更改的日期更改 如果有一些 Windows api 在 SYSTEMTIME
  • 有什么理由不在Python中混合使用多处理和线程模块

    我正在考虑使用Python来实现一个需要大量多线程的程序 另一个要求是它将在桌面上运行 因此拥有许多进程将使应用程序显得混乱且难以杀死 在任务管理器中 因此 我正在考虑使用线程和多处理模块来减少进程数量 据我了解 GIL 仅适用于单个进程
  • 使用 INF 文件 C++ 以编程方式安装驱动程序

    这里有人可以告诉我如何安装第 3 方设备驱动程序吗 如果提供了所有必需的文件 即 inf 文件 sys 等 则以编程方式进行 这 该解决方案应运行的最低操作系统是Windows2000 我尝试复制 inf文件放入Win文件夹 INF文件夹和
  • 谷歌基准迭代的意义是什么?

    我正在使用 Google Benchmark 来测量某些代码的执行时间 例如 我编写了以下代码来测量其执行时间性能 include
  • 检查 Win32 线程是否正在运行或处于挂起状态

    如何检查 Win32 线程是否正在运行或处于挂起状态 我找不到任何提供线程状态的 Win32 API 那么如何获取线程状态呢 我认为 最初 没有提供此信息 因为任何提供此信息的 API 都会产生误导且无用 考虑两种可能的情况 当前线程已挂起
  • 使 GetRawInputDeviceInfo 和 RIDI_DEVICEINFO 与 C# 一起使用

    我有一个问题 我似乎无法使 GetRawInputDeviceInfo 与 RIDI DEVICEINFO 结合使用 尝试检索 RID DEVICE INFO 根本不起作用 我从函数中得到错误 1 这意味着没有足够的空间来存储 RID DE
  • 为什么非交互式批处理脚本认为我按下了 Control-C?

    因此 当输出日志中突然出现以下内容时 我的批处理脚本运行得很好 21 27 13 99 c apps w7lab scripting gt some command Error 3221225786 CTerminate batch job
  • 如何使用 Anaconda Python 执行 .py 文件?

    我刚刚在我的 Windows 计算机上下载并安装了 Anaconda 但是 我在使用命令提示符执行 py 文件时遇到问题 如何让我的计算机了解 python exe 应用程序位于 Anaconda 文件夹中 以便它可以执行我的 py 文件
  • 发送/捕获 SIGTERM 的 Win32 API 模拟

    在 POSIX OS 下 有信号 API 允许向进程发送信号以将其关闭 使用kill 您可以使用sigaction捕获它并执行您需要的操作 然而 Win32不是POSIX系统 所以 如何处理可能出现的关闭事件 例如来自 任务管理器 中的 结
  • “composer”在 Windows 服务器中未被识别为内部或外部命令

    我使用的是Windows Server 2008操作系统 我下载作曲家安装程序 exe https getcomposer org download 并安装到我的电脑上 当我尝试时composer install 我收到错误 compose
  • Windows 上 PE 文件 (exe) 的最小文件大小是多少?以及最小内存分配? [复制]

    这个问题在这里已经有答案了 Windows 上 PE 文件 exe 的最小文件大小是多少 以及最小内存分配 我 使用 VS 10 附带的 MASM ml exe 和 link exe 组装了以下代码 我不能忽略 kernel32 lib 和
  • 如何计算 WPF 中的非客户端窗口大小?

    WPF 有SystemParameters class http msdn microsoft com en us library system windows systemparameters aspx公开了大量的系统指标 在我的计算机上
  • 在VB.net中动态添加用户控件

    我在 Vb net Windows 应用程序 中制作了自定义 UserControl 如何将其动态添加到表单中 UserControl 本质上只是另一个类 它继承自 Control 因此您可以使用控件执行各种操作 但除此之外它只是一个类 因
  • 我可以在 Emacs 的 shell 模式下使用 PowerShell 吗?

    我可以在 emacs 的 shell 模式下使用 powershell 作为 shell 吗 How 请参阅 Jeffrey Snover 的博客文章在 Emacs 内运行的 PowerShell http blogs msdn com p
  • 如何使用C++在Windows中获取MAC地址? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 Windows 上使用 pycrypto 时如何修复“ImportError:无法从 Crypto.Cipher 导入名称 _AES”?

    我在 Crypto 的 Cipher 模块中有 AES Python27 Lib Crypto Cipher AES 当我尝试做的时候 from Crypto Cipher import AES 我收到以下错误 Traceback most

随机推荐

  • Linux系统下安装Java环境

    目录 测试环境 下载JDK 终端模拟软件 安装前准备 tar包的安装方法 tar包的卸载 rpm包的安装方法 rpm包的卸载 测试环境 LInux系统版本 xff1a CentOS 7 64位 终端模拟软件 xff1a Xshell 6 J
  • 【Hexo】Hexo个人博客绑定域名

    Hexo个人博客绑定域名 当我们在用hexo搭建了个人博客之后 xff0c 用username github io访问难免有些奇怪 xff0c 下面就花3分钟时间对如何绑定个人域名进行描述 我这边是在阿里云买的一个域名 xff0c ycbl
  • 生产者消费者的代码实现

    当消费者获得的数据为大写字母时 xff0c 则把大写字母转换成小写字母 xff0c 并显示 xff1b 当消费者获得的数据为小写字母时 xff0c 则把小写字母转换成大写字母 xff0c 并显示 xff1b 当消费者获得的数据为字符0 1
  • 基于RobHess的SIFT图像拼接知识点随笔

    1 SIFT算法具有尺度不变性在于构建的高斯尺度空间 xff1b 2 SIFT算法具有旋转不变性在于特征方向向量 xff1b 3 K d数以图像特征点的128维特征描述子均值为依据进行划分 构建 xff1b 4 特征点匹配是一个图像的所有特
  • 最小二乘法及OpenCv函数

    1 最小二乘法 我们以最简单的一元线性模型来解释最小二乘法 什么是一元线性模型呢 xff1f 监督学习中 xff0c 如果预测的变量是离散的 xff0c 我们称其为分类 xff08 如决策树 xff0c 支持向量机等 xff09 xff0c
  • Linux服务器网络不通情况分析以及常见检查方法

    在实际运维过程中 xff0c 经常会遇到网路不通的问题 xff0c 一般此类网络不通的问题都是业务端到端的排查 本文从后端linux服务器端自查是否服务器问题 通过多年的运维经验总结 xff0c 服务器端问题导致网络不通 xff0c 大致分
  • RANSAC算法实现去除误匹配并计算拼接矩阵-随笔

    1 RANSAC算法实现去除误匹配并计算拼接矩阵流程 1 从样本集中随机抽选一个RANSAC样本 xff0c 即4个匹配点对 xff08 至少4个匹配点对 xff0c 才能计算出3 3变换矩阵 xff09 xff1b 2 计算当错误概率为0
  • linux c++ 服务器端开发面试必看书籍

    由于很多朋友希望加入到Linux c 43 43 服务器端开发的队伍中 xff0c 本人就结合自己的面试经历并整理了自己阅读的相关书籍 xff0c 同大家分享 xff0c 一起进步 人个认为以下是进入这个方向的必看书籍 xff0c 各系列难
  • C++进阶—>const、define和enum的区别和用途

    1 区别 这三种都可以定义常量 define是宏定义 xff0c 编译器不对其进行错误检查 xff0c 在预编译阶段处理 xff0c 没有作用域限制属于全局常量 xff0c 在程序中编译器会对定义的常量名以数值进行替换 xff0c 且每次替
  • MFC中基于OpenCV实现Picture Control控件成像方法

    MFC中基于OpenCV实现Picture Control控件成像方法有两种 xff0c 一种是OpenCV2 2以前版本的绘制 xff0c 另外一种是OpenCV2 2以后版本的绘制 xff08 1 xff09 在OpenCV2 2之前的
  • MFC中CFileDialog及SHBrowseForFolder

    MFC中实现通过按钮来选择文件路径或文件夹路径 xff1b xff08 1 xff09 CFileDialog类能够选择文件 xff0c 并获取其路径 xff08 当然也可以通过获取文件路径再去除文件名而获得其所在文件夹路径 xff0c 前
  • C++进阶—>带你理解多字节编码与Unicode码

    本篇文章将讲解C 43 43 开发中容易混淆的另一个概念 多字节字符集与Unicode字符集 多字节字符与宽字节字符 char与wchar t 我们知道C 43 43 基本数据类型中表示字符的有两种 xff1a char wchar t c
  • BP神经网络及其C++实现

    0 前言 神经网络在我印象中一直比较神秘 xff0c 正好最近学习了神经网络 xff0c 特别是对Bp神经网络有了比较深入的了解 xff0c 因此 xff0c 总结以下心得 xff0c 希望对后来者有所帮助 神经网络在机器学习中应用比较广泛
  • C++进阶—>Socket通信那点事

    1 网络中进程之间如何通信 xff1f 本地的进程间通信 xff08 IPC xff09 有很多种方式 xff0c 但可以总结为下面4类 xff1a 消息传递 xff08 管道 FIFO 消息队列 xff09 同步 xff08 互斥量 条件
  • C++进阶—>线程同步随笔

    线程同步主要有五种方法 xff1a 原子访问 xff0c 临界区 xff0c 信号量 xff0c 事件和互斥量 xff1b 其中原子访问和临界区属于用户模式的同步 xff1b 信号量 xff0c 事件和互斥量属于内核模式的同步 原子访问是通
  • C++进阶—>_beginthreadex和CreateThread的区别和联系

    beginthread 和 CreateThread 的区别 转自 http wenku baidu com view adede4ec4afe04a1b071dea4 html 程序员对于Windows程序中应该用 beginthread
  • idea src下源文件和class编译文件不一致

    今天遇到一个神奇BUG xff0c 一个和elasticsearch没有任何关系的项目 xff0c 报错ES某个包找不到 xff0c 刚开始以为是依赖了父项目的某个包 xff0c 并且本项目主启动类ComponentScan扫描了相关的类进
  • C++进阶—>Win32 多线程的创建方法和基本使用

    Summary From xff1a https software intel com zh cn blogs 2011 12 02 win32 cid 61 sw prccsdn2086 总结Win32提供的创建多线程相关的API接口和基
  • Windows核心编程之多进程概述

    一 进程的概念 进程是是一个正在运行的程序的实例 xff08 飘 xff5e xff5e xff5e xff09 xff0c 是系统分配资源的单位 线程是执行的单位 xff0c 包括内存 xff0c 打开的文件 处理机 外设等 xff0c
  • Windows核心编程之进程间通信

    1 进程与进程通信 进程是装入内存并准备执行的程序 xff0c 每个进程都有私有的虚拟地址空间 xff0c 由代码 数据以及它可利用的系统资源 如文件 管道等 组成 多进程 多线程是Windows操作系统的一个基本特征 Microsoft