【问题标题】:What are the differences between pipes in Windows and Linux?Windows 和 Linux 中的管道有什么区别?
【发布时间】:2010-09-16 13:33:00
【问题描述】:

Windows 和 Linux 中的管道有什么区别?

【问题讨论】:

    标签: language-agnostic ipc pipe named-pipes


    【解决方案1】:

    我知道的一个区别是,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,这会很方便,因为这样你就可以同时运行这两个操作,以获得很好的加速。

    【讨论】:

    • 投反对票。在 Windows 上,我可以使用 CreateFile、ReadFile、WriteFile、ReadFileEx、WriteFileEx 函数来命名管道。只有服务器必须使用 CreateNamedPipe。有用于同步管道创建和绑定的管道功能,但如果不需要网络管道,可以使用命名等待事件来替换这些功能。
    • Windows 本地命名管道使用下面的内存映射文件。这意味着管道将数据存储在内存中或pagefile.sys中。
    • Windows 没有使用根文件系统,而是有一个根对象树,它持久保存在注册表中并动态填充。 \\.\\\?\ 类似 UNC 的前缀(它们并不是真正的 UNC)被映射到本机对象管理器 \?? 虚拟目录。这会在\Sessions\0\DosDevices\[LOGON ID] 中查找您的登录会话设备链接,然后在\Global?? 中查找系统设备链接。
    • 系统设备\Global??\Pipe 是指向\Device\NamedPipe 的对象符号链接。该设备由 NamedPipe 文件系统管理(即对象树中的\FileSystem\Npfs)。您可以列出系统上的所有命名管道。它不支持真正的目录,但通常在名称中使用反斜杠创建管道来模拟它,例如\Device\NamedPipe\Winsock2\CatalogChangeListener-xxx-0.
    • @vincent,我不完全遵循您的问题的意图。管道文件是在命名管道文件系统中创建的,该文件系统安装在管道设备的根路径下,即“//./pipe/”。您可以通过FindFirstFileW(L"//./pipe/*", &findData)FindNextFileW 列出目录中的管道。您可以通过GetFileAttributesW(L"//./pipe/SomeNamedPipe") 检查命名管道是否存在,但它确实会消耗管道连接。如果它以ERROR_PIPE_BUSY (231) 失败,则管道存在但没有可用的实例。
    【解决方案2】:

    另一个重要的区别

    窗户下

    A | B | C 
    

    直到A完成它的输出B才开始读取,C读取B输出也是如此

    *nix 将输入和输出挂钩,以便 C 可以读取 B 的输出,而 B 可以在 A 和 B 仍在运行时读取 A 的输出

    吞吐量大致相同,但使用 *nix 时输出显示速度更快。

    【讨论】:

    • 这就是我要找的东西:我似乎记得是这种情况,但不确定。谢谢!
    • 这样做的结果是缓冲区的大小在 UNIX 上可以小得多。 UNIX 管道允许您处理任意数量的数据,而 Windows 管道在处理足够的数据时会停止运行。
    【解决方案3】:

    在 Linux(和一般的 *ix)下,“一切都是文件”。您可以不受限制地读取/写入/查找管道、套接字和设备,只要这些操作有意义。

    而对于这些不同类型的对象,Windows 的架构远没有那么统一。虽然我不能告诉你细节,但我知道 Windows 和 Linux 之间的管道缓冲有很大不同,所以你可能会遇到困难。

    此外,Unix-y 对管道的一种常见用法是fork() 一个子进程,然后通过管道与其通信(父进程打开一端,子进程打开另一端)。在 Windows 下,这种事情是不可能的。 IPC 机制完全不同。

    【讨论】:

    • Windows 中的子进程显然可以继承管道句柄,所以我想你的意思是 fork() 是不可能的。内核可以fork;这是对基本内存管理器服务的非常直接的使用,但在 Windows API 中实现它可能几乎是不可能的。即使在 Unix 上,fork 的不当使用也可能是一场灾难,而在一个专为它设计的系统上,人们在创建解决方案时考虑到了 fork。
    【解决方案4】:

    参见上一个帖子:

    What are named pipes?

    其中包含我和其他几个人的观点

    【讨论】:

      猜你喜欢
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      • 2013-09-05
      • 2020-03-21
      • 2015-02-02
      相关资源
      最近更新 更多