【问题标题】:Unwanted buffering when filtering console output in Win32在 Win32 中过滤控制台输出时不需要的缓冲
【发布时间】:2010-06-24 18:45:54
【问题描述】:

我的问题与"Turn off buffering in pipe" 有关,尽管是关于 Windows 而不是 Unix。

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

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

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

那么……有什么理智的方法可以解决这个问题吗?

【问题讨论】:

    标签: winapi process pipe console-application


    【解决方案1】:

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

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

    【讨论】:

    • 这样做不仅是为了提高性能,也是为了符合标准。 C99,第 7.19.3/7 节:“...标准输入和标准输出流被完全缓冲当且仅当流可以确定不引用交互式设备。”
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-18
    • 2015-03-27
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    相关资源
    最近更新 更多