【问题标题】:std::cout overhead if closed (STDIN_FILENO)关闭时的 std::cout 开销 (STDIN_FILENO)
【发布时间】:2014-09-23 05:12:00
【问题描述】:

我有后台进程(unix 系统上的守护进程),在某些地方有 std::cout 用于调试源文件。我在静音模式或无静音模式下运行此守护程序。在进程开始后silence mode 上,我执行这段代码:

std::cout.rdbuf(0);
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);   

如您所知,std::cout 仍然存在于代码中并运行。

NON silence mode有很大的开销,而cout对屏幕的开销很大而且IO操作很慢。

问题: silence mode 上的代码开销是多少?由于std::cout 的存在,我的程序是否存在一些“阻力”,但STDOUT_FILENO 已关闭? (有时它会尝试打印多达 1 KB 的信息)

这个开销有多大?

【问题讨论】:

  • 使用另一个streambuf 对象不是更好吗?假设clog 构造为在您需要此类数据时使用cout,而当您在静默模式下运行时使用nothing(只是丢弃输入)?点 (IMO) 不是开销是否很大(只是衡量),而是是否清楚。
  • 我不知道,我使用这个解决方案是因为如果 deamon 在调试(非静音模式)时很容易在屏幕上打印一些东西,并且在工作环境中很容易关闭所有 cout。但我怀疑这个解决方案有一些开销。如果 cout 关闭 STDOUT_FILENO 没有开销(例如,如果在函数开始时检查 STDOUT_FILENO 是否打开),似乎你建议像我这样的东西
  • 您可以简单地将所有std::cout 替换为yourapp::clog,它会起作用。你只需要根据选项初始化clog。开销...嗯,我认为(但我认为这不是衡量标准)一半将与您构建的字符串/您准备的数据一起提供(如果您只是将输出降至 null,它将无法避免)。
  • @AdrianoRepetti 使用只丢弃输出的 streambuf 是经典的解决方案,但它会导致所有转换发生,这是不可忽略的。

标签: c++ cout overhead


【解决方案1】:

它显然有一些开销。但并不多;每个<< 的第一件事是测试流状态是否良好。如果相应的物理设备关闭,不应该。至少,在第一次刷新后它会变坏(由于缓冲区变满)。或者,您可以致电std::cout.rdbuf( nullptr ),这应该会立即使其变坏。

传统的解决方案是创建一个无操作流缓冲区。这样做的好处是流不会变坏:读取总是看到文件结尾,并且输出总是有效。它有一个缺点,因为流状态很好,你实际上格式化了所有的输出:std::cout << someDouble 将完成将双精度转换为字符序列的所有工作。如果流状态不好(因为它将使用 nullptr 作为流缓冲区),<< 运算符在尝试转换任何内容之前返回。

【讨论】:

  • 感谢您的回答。对于我的情况,也许还有其他不错的选择?
猜你喜欢
  • 1970-01-01
  • 2020-03-12
  • 2020-08-21
  • 2016-02-26
  • 1970-01-01
  • 2021-08-04
  • 2014-06-24
  • 2015-10-10
  • 2010-10-12
相关资源
最近更新 更多