我仍然经常使用控制台输出来获取我的代码中发生的事情.我知道这可能有点老式,但我也用它来"管道"stdout到日志文件等.
但是,事实证明,由于某种原因,控制台的输出速度变慢了.我想知道是否有人可以解释为什么fprintf()到控制台窗口似乎有点阻塞.
到目前为止我做过/诊断过的事情:
我测量了fprintf(stdout,"quick fprintf\n");
它需要的时间
:0.82ms(平均值).由于vsprintf_s(...)在几微秒内将相同的输出写入字符串,因此考虑的时间太长.因此,必须有一些专门针对控制台的阻止.
为了摆脱阻塞,我习惯vsprintf_s(...)将输出复制到一个类似于fifo的数据结构中.数据结构受临界区对象的保护.然后,单独的线程通过将排队的输出放入控制台来对数据结构进行取消.
我可以通过引入管道服务获得进一步的改进.我的程序的输出(应该最终在控制台窗口中)按以下方式进行:
vsprintf_s(...)将输出格式化为简单字符串.fprintf(stdout,...)到控制台.所以我有两个进程,每个进程至少有两个线程,它们之间有一个命名管道,管道两侧有类似数据结构,以避免在管道缓冲区满时阻塞.
这是很多东西,以确保控制台输出是"非阻塞".但结果并不算太糟糕.我的主程序可以在几微秒内编写复杂的fprintf(stdout,...).
也许我之前应该问过:还有其他(更容易!)的方式来获得非阻塞控制台输出吗?
das*_*ght 13
我认为时间问题与控制台默认为线缓冲这一事实有关.这意味着每次'\n'向其写入一个字符时,整个输出缓冲区都会被发送到控制台,这是一项相当昂贵的操作.这是您为直接在输出中显示的行支付的价格.
您可以通过将缓冲策略更改为完全缓冲来更改此默认行为.结果是输出将以等于缓冲区大小的块发送到控制台,但单个操作将更快完成.
在第一次写入控制台之前进行此调用:
char buf[10000];
setvbuf(stdout, buf, _IOFBF, sizeof(buf));
Run Code Online (Sandbox Code Playgroud)
单个写入的时间应该会改善,但输出不会立即出现在控制台中.这对于调试来说不太有用,但时间会有所改善.如果你设置一个fflush(stdout)定时调用的线程,比如每秒调用一次,你应该在单个写操作的性能和编写输出的程序之间的延迟和实际看到它的时间之间得到合理的平衡.控制台.