无缓冲的 CreateNamedPipe 用作 CreateProcess 的标准输出
我想执行任意命令行应用程序并在生成时读取其标准输出。我使用 CreateNamedPipe 创建管道,然后将另一端(打开使用的 CreateFile)提供给 CreateProcess。如果目标进程没有显式地使用标准输出缓冲进行操作,是否有一种方法可以确保有问题的管道没有缓冲,或者至少使用系统最小值作为缓冲区大小?
I would like to execute arbitrary command-line application and read its standard output as it gets produced. I use CreateNamedPipe
to create a pipe and then supply other end (open used CreateFile
) to CreateProcess
. Provided the target process doesn't explicitly manipulates with standard output buffering is there a way to make sure that pipe in question is unbufferred or at least that the system minimum is used as buffer size?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您无法真正控制缓冲区大小。您可以将读取和写入缓冲区大小 1 传递给
CreateNamedPipe
,但内核会自动增加这些缓冲区大小。基本上,缓冲区将始终至少与任何给定时间已准备好读取的最大数据量一样大。换句话说,对可用数据的响应速度越快,写入管道的数据块越小,保留的缓冲区就越小。但是,我认为缓冲区大小并不真正重要。管道不会延迟数据的发送,直到缓冲区“满”为止,并且没有什么相当于 TCP 的“nagle”选项,因此保持较小的缓冲区大小不会改善延迟。
请记住,当您将管道连接到控制台应用程序的 stdout 时,输出通常会在写入管道之前由该应用程序缓冲。如果您想要无缓冲输出,则需要使用 stderr。
另外,使用继承的管道句柄时需要注意的是,生成的应用程序将继承所有句柄,因此,如果您打开了一个文件或套接字,则生成一个应用程序,然后关闭该句柄、文件/套接字等。将保持打开状态,直到生成的子进程停止,这可能会导致意外的共享冲突和其他奇怪的问题。
You can't really control the buffer sizes. You can pass in read and write buffer sizes of 1 to
CreateNamedPipe
, but the kernel will automatically increase those buffer sizes. Basically, the buffer will always be at least as large as the largest amount of data that has been ready to read at any given time. Put another way, the faster you respond to data being available, and the smaller the blocks of data written to the pipe, the smaller the buffer will remain.However, I don't think the buffer sizes are really important. Pipes do not delay the sending of data until the buffer is "full", and there's nothing equivalent to the "nagle" option for TCP, so maintaining a small buffer size will not improve your latency.
Keep in mind that when you connect a pipe to a console application's
stdout
, the output is typically buffered by that application before it's written to the pipe. If you want unbuffered output, you will need to use stderr.Also, something to watch out for when using inherited pipe handles is that the spawned application will inherit all your handles, so if you have a file or a socket open, you spawn an application, then close that handle, the file/socket/etc. will remain open until the spawned child process stops, which can lead to unexpected sharing violations and other strange problems.