我仍然经常使用控制台输出来了解代码中正在发生的情况。
我知道这可能有点老式,但我也使用它来将stdout“导入”日志文件等。
然而,事实证明,控制台输出的速度会因某种原因而变慢。我想知道有人能否解释一下为什么fprintf()到控制台窗口似乎是阻塞的。
我迄今为止所做/诊断的内容:
我测量了一个简单的操作所需的时间
fprintf(stdout,"quick fprintf\n");
需要:0.82毫秒(平均值)。由于vsprintf_s(...)
仅在几微秒内将相同的输出写入字符串,因此这被认为是太长了。因此必须有特定于控制台的一些阻塞。为了逃避这种阻塞,我使用
vsprintf_s(...)
将我的输出复制到类似fifo的数据结构中。该数据结构由关键部分对象保护。然后,一个单独的线程通过将排队的输出放入控制台来取消排队数据结构。通过引入管道服务,我可以获得进一步的改进。我的程序的输出(假定最终显示在控制台窗口中)经过以下方式:
- 使用
vsprintf_s(...)
格式化输出为简单字符串。 - 将字符串排队到类似fifo的数据结构中,例如链表结构。该数据结构由关键部分对象保护。
- 第二个线程通过将输出字符串发送到命名管道来取消对数据结构的排队。
- 第二个进程读取命名管道并将字符串再次放入类似fifo的数据结构中。这是为了使阅读远离阻塞的控制台输出。读取过程快速读取命名管道并连续监视管道缓冲区的填充级别。
- 第二个进程中的第二个线程最终通过
fprintf(stdout,...)
向控制台取消排除数据结构。
- 使用
我有两个至少有两个线程的进程,它们之间有一个命名管道,管道两端都有类似fifo的数据结构以避免管道缓冲区满时阻塞。
这些步骤都是为了确保控制台输出是“非阻塞”的,但结果还不错。我的主程序可以在几微秒内写入复杂的fprintf(stdout,...)。
也许我应该早点问:是否有其他(更简单!)的方法来实现非阻塞控制台输出?
FILE
(并使用具有大缓冲区的setvbuf
)。 - Basile Starynkevitchstdout
,平均每次运行10000次调用fprintf(stdout,“quick fprintf\n”);
需要0.000023904秒。 - Maxim Egorushkin