无缓冲的CreateNamedPipe用作CreateProcess的标准输出

时间:2009-10-14 22:46:57

标签: winapi pipe named-pipes createprocess output-buffering

我想执行任意命令行应用程序并在生成时读取其标准输出。我使用CreateNamedPipe创建了一个管道,然后将另一端(打开使用CreateFile)提供给CreateProcess。如果目标进程没有使用标准输出缓冲显式操作,是否有办法确保所讨论的管道是非缓冲的,或者至少将系统最小值用作缓冲区大小?

1 个答案:

答案 0 :(得分:4)

您无法真正控制缓冲区大小。您可以将读取和写入缓冲区大小1传递给CreateNamedPipe,但内核会自动增加这些缓冲区大小。基本上,缓冲区始终至少与在任何给定时间准备好读取的最大数据量一样大。换句话说,您对可用数据的响应速度越快,写入管道的数据块越小,缓冲区将保留得越小。

  

输入和输出缓冲区大小是建议性的。为命名管道的每一端保留的实际缓冲区大小是系统默认值,系统最小值或最大值,或指定的大小向上舍入到下一个分配边界。 ...每当发生管道写入操作时,系统首先尝试根据管道写入配额对内存进行充电。 ...如果剩余的管道写入配额太小而无法满足请求,系统将尝试使用为该进程保留的非分页池来扩展缓冲区以容纳数据。

但是,我认为缓冲区大小并不重要。在缓冲区“满”之前,管道不会延迟数据的发送,并且没有任何东西等同于TCP的“nagle”选项,因此保持较小的缓冲区大小不会改善延迟。

请记住,当您将管道连接到控制台应用程序的stdout时,输出通常由该应用程序缓冲,然后将其写入管道。如果您想要无缓冲输出,则需要使用stderr。

另外,在使用继承的管道句柄时要注意的是,生成的应用程序将继承所有句柄,因此如果打开文件或套接字,则会生成一个应用程序,然后关闭该句柄,文件/插座/等。将继续打开,直到产生的子进程停止,这可能导致意外的共享违规和其他奇怪的问题。