5

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

4

1 回答 1

4

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

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

但是,我不认为缓冲区大小真的很重要。在缓冲区“满”之前,管道不会延迟数据的发送,并且没有什么相当于 TCP 的“nagle”选项,因此保持较小的缓冲区大小不会改善您的延迟。

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

此外,使用继承的管道句柄时要注意的一点是,生成的应用程序将继承所有句柄,因此如果您打开了一个文件或套接字,则生成一个应用程序,然后关闭该句柄,文件/套接字/等. 将保持打开状态,直到生成的子进程停止,这可能导致意外的共享冲突和其他奇怪的问题。

于 2009-10-14T22:58:33.867 回答