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

发布于 2024-08-08 00:12:40 字数 165 浏览 8 评论 0原文

我想执行任意命令行应用程序并在生成时读取其标准输出。我使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡淡绿茶香 2024-08-15 00:12:40

您无法真正控制缓冲区大小。您可以将读取和写入缓冲区大小 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.

The input and output buffer sizes are advisory. The actual buffer size reserved for each end of the named pipe is either the system default, the system minimum or maximum, or the specified size rounded up to the next allocation boundary. ... Whenever a pipe write operation occurs, the system first tries to charge the memory against the pipe write quota. ... If the remaining pipe write quota is too small to fulfill the request, the system will try to expand the buffers to accommodate the data using nonpaged pool reserved for the process.

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文