在 Win32 中过滤控制台输出时出现不需要的缓冲

发布于 2024-09-07 15:10:42 字数 588 浏览 9 评论 0原文

我的问题与“关闭管道中的缓冲”有关,尽管涉及Windows而不是Unix 。

我正在编写一个 Make 克隆并阻止并行进程破坏彼此的控制台输出,我已将输出重定向到管道(如 此处),我可以在其中进行任何我想要的过滤。不幸的是,长时间运行的进程现在会缓冲其输出,而不是像在控制台上那样实时发送。

从 MSVCRT 源代码来看,根本原因似乎是 GetFileType() 用于检查标准 I/O 句柄是否连接到控制台,然后设置一个内部标志并最终禁用缓冲。

显然,在创建进程时,还可以通过 STARTUPINFO 结构的未记录的 lpReserved2 成员传递一个单独的可继承文件句柄和标志数组。我想出的唯一可行的解​​决方案是使用此列表,并在设置 stdout/stderr 标志时谎报设备类型。

那么现在...有什么合理的方法来解决这个问题吗?

My question is related to "Turn off buffering in pipe" albeit concerning Windows rather than Unix.

I'm writing a Make clone and to stop parallel processes from thrashing each others' console output I've redirected the output to pipes (as described in here) on which I can do any filtering I want. Unfortunately long-running processes now buffer up their output rather than sending it in real-time as they would on a console.

From peeking at the MSVCRT sources it seems the root cause is that GetFileType() is used to check whether the standard I/O handles are attached to a console, which then sets an internal flag and ends up disabling buffering.

Apparently a separate array of inheritable file handles and flags can also be passed on through the undocumented lpReserved2 member of the STARTUPINFO structured when creating the process. About the only working solution I've figured out is to use this list and just lie about the device type when setting the flags for stdout/stderr.

Now then... Is there any sane way of solving this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

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

发布评论

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

评论(1

故事还在继续 2024-09-14 15:10:42

没有。是的,GetFileType() 告诉它 stdout 不再是字符设备,_isatty() 返回 false,因此 CRT 将输出流切换到缓冲模式。获得合理的吞吐量很重要。仅当人类正在查看它们时,一次刷新一个字符的输出才是可接受的。

您必须使用自定义版本的 CRT 重新链接尝试重定向的程序。我毫不怀疑,如果这是可能的,你一开始就不会搞砸这个。修补 GetFileType() 是另一个不理智的​​解决方案。

There is not. Yes, GetFileType() tells it that stdout is no longer a char device, _isatty() return false so the CRT switches the output stream to buffered mode. Important to get reasonable throughput. Flushing output one character at a time is only acceptable when a human is looking at them.

You would have to relink the programs you are trying to redirect with a customized version of the CRT. I don't doubt that if that was possible, you wouldn't be messing with this in the first place. Patching GetFileType() is another un-sane solution.

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