Windows进程间通信的主要缺点是什么?

假设你将一个单一的Windows程序拆分成可重用的组件,这些组件可以使用某种进程间通信 (IPC) 相互通信 ,并且无论出于何种原因,你都可以select匿名pipe道(例如启动一些Process-es和将Console.Out连接到Console.In的下一个进程,或者只是在命令提示符下使用“|”)。

Dobbs博士的一篇文章用一个命名pipe道的例子:

与同一机器中的其他IPC方法相比,性能会受到怎样的影响? 在扩展进程数量或传输数据量时,遇到的第一个问题是什么?

例如,如果我们使用文件而不是pipe道,我们会遇到locking问题和磁盘速度。

请注意,通过序列化正在传输的数据结构,已经有一个开销,这是我的效率损失的基准。

PS。 对pipe道的兴趣是因为它们很容易在每个进程中实现(Console.Readline,Console.WriteLine),所以很容易编写MSMQ和asynchronousHTTP接口,以及Unix和命令行的爱好。

Solutions Collecting From Web of "Windows进程间通信的主要缺点是什么?"

您可以使用CreatePipe()Win32 API调用创建双向匿名管道,因此管道输入/输出不是唯一的方法。 你只需得到一个新的文件句柄,你可以给另一个进程。

匿名管道基于共享内存,但不支持异步操作(通过ReadFileEx,ReadFileWrite)。 性能问题(缺点)因此是1)同步操作,2)存储器复制,3)进程间同步。 一般来说,“原始的”共享内存(内存映射文件没有实际的后备文件)和命名管道会更快,并且套接字和窗口消息将比匿名管道更慢。

您不能使用具有匿名管道的I / O完成端口(IOCP),而是必须“轮询”管道,导致额外的上下文切换。 除了序列化数据之外,序列化的数据必须在内存中复制,因为不能直接写入共享内存。 一个进程也必须等待另一个进程,意味着另一个进程必须发信号通知一个进程间同步原语。 性能在很大程度上取决于消息的大小(读/写调用与发送数据量的比率),因为对于每个读/写过程必须进行上下文切换以及可能的旋转/休眠。

除“原始”共享内存之外的所有方法都需要内存复制和某种进程间信令(同步),所以匿名管道的主要缺点是同步操作。 传输大量消息时,CPU将花费大部分时间进行上下文切换。

性能方面,命名管道更好,因为您可以让工作线程使用IOCP处理异步通知,甚至可以通过一次调用接收多个消息,从而减少API开销。 如果制作自己的组件,给管道一个名字带来的额外麻烦是非常值得的(你甚至可以通过网络连接)。 后来的Windows版本为本地套接字实现特殊的路由,也支持IOCP。

最快的方法是直接使用共享内存,但是您必须自己处理进程间同步。 你可以自己实现无锁的管道,但是如果你不经常传输数据,你仍然需要使用同步原语来通知/唤醒监听过程。

另外请注意,使用文件并不意味着您将受到磁盘速度的限制,因为您可以使用内存映射文件,甚至使用普通文件,缓存管理器将处理读/写操作。 其他方法(RPC,剪贴板等)基于这些“标准”方法,这意味着它们只会添加一些额外的协议层,意味着更容易/更有帮助,或更适合某些编程环境(但不要更快)。