【发布时间】:2010-09-16 13:33:00
【问题描述】:
Windows 和 Linux 中的管道有什么区别?
【问题讨论】:
标签: language-agnostic ipc pipe named-pipes
Windows 和 Linux 中的管道有什么区别?
【问题讨论】:
标签: language-agnostic ipc pipe named-pipes
我知道的一个区别是,Linux 下的命名管道是文件系统中的实际条目(您会在目录列表中看到它,它们具有特殊类型),而在 Windows 上它们存储在一些神奇的存储库中某处(它们都通过路径“\\.\pipe\”访问。
其次,在 Linux 中,您可以使用标准文件 IO 方法从管道中写入/读取,就好像它们是任何其他文件一样。而在 Windows 上,您必须使用 Win32 API 中的特殊“管道”函数。
我更喜欢 linux 的方法,因为它让我可以在任何我想要的应用程序中使用管道。例如:
mkfifo pipe.wav
decodeMP3 song.mp3 --out pipe.wav &
encodeAVI video.mpeg pipe.wav --out video.avi
这让我可以将 MP3 解码器的输出直接通过管道传输到视频解码器中,而不必先将整个 MP3 解码为磁盘上的 WAV 文件。如果你有一个双核 CPU,这会很方便,因为这样你就可以同时运行这两个操作,以获得很好的加速。
【讨论】:
\\.\ 和 \\?\ 类似 UNC 的前缀(它们并不是真正的 UNC)被映射到本机对象管理器 \?? 虚拟目录。这会在\Sessions\0\DosDevices\[LOGON ID] 中查找您的登录会话设备链接,然后在\Global?? 中查找系统设备链接。
\Global??\Pipe 是指向\Device\NamedPipe 的对象符号链接。该设备由 NamedPipe 文件系统管理(即对象树中的\FileSystem\Npfs)。您可以列出系统上的所有命名管道。它不支持真正的目录,但通常在名称中使用反斜杠创建管道来模拟它,例如\Device\NamedPipe\Winsock2\CatalogChangeListener-xxx-0.
FindFirstFileW(L"//./pipe/*", &findData) 和FindNextFileW 列出目录中的管道。您可以通过GetFileAttributesW(L"//./pipe/SomeNamedPipe") 检查命名管道是否存在,但它确实会消耗管道连接。如果它以ERROR_PIPE_BUSY (231) 失败,则管道存在但没有可用的实例。
另一个重要的区别
窗户下
A | B | C
直到A完成它的输出B才开始读取,C读取B输出也是如此
*nix 将输入和输出挂钩,以便 C 可以读取 B 的输出,而 B 可以在 A 和 B 仍在运行时读取 A 的输出
吞吐量大致相同,但使用 *nix 时输出显示速度更快。
【讨论】:
在 Linux(和一般的 *ix)下,“一切都是文件”。您可以不受限制地读取/写入/查找管道、套接字和设备,只要这些操作有意义。
而对于这些不同类型的对象,Windows 的架构远没有那么统一。虽然我不能告诉你细节,但我知道 Windows 和 Linux 之间的管道缓冲有很大不同,所以你可能会遇到困难。
此外,Unix-y 对管道的一种常见用法是fork() 一个子进程,然后通过管道与其通信(父进程打开一端,子进程打开另一端)。在 Windows 下,这种事情是不可能的。 IPC 机制完全不同。
【讨论】:
fork() 是不可能的。内核可以fork;这是对基本内存管理器服务的非常直接的使用,但在 Windows API 中实现它可能几乎是不可能的。即使在 Unix 上,fork 的不当使用也可能是一场灾难,而在一个专为它设计的系统上,人们在创建解决方案时考虑到了 fork。
【讨论】: