【问题标题】:Synchronizing STD cout output in a boost::thread without control over threads在 boost::thread 中同步 STD cout 输出而不控制线程
【发布时间】:2015-04-01 18:53:50
【问题描述】:

我想问与这里问的完全相同的问题: Synchronizing STD cout output multi-thread 唯一的例外是我无法控制使用 boost::thread 的代码(该代码是 this library 的内部代码,我不应该/不想触摸它,除非这个问题不能以任何其他方式解决,在这种情况下,我可以将它添加到我的库中。)

库在某个时间在 C++ 代码中生成 4 个线程(我在使用 OSX 10.10 的 2010 年中期 MacBook Pro 上)在我使用 cout 进行日志记录的单个线程中执行,如下所示:

cout << "Writing file: " << "\n" << xmlFileName << endl;

由于多线程,此输出会出现乱码,因此在任何给定时刻都很难理解单个线程中发生了什么......

如何使输出同步?该项目使用 Boost 1.57.0,所以我可以使用它。我以前从未处理过多线程,但我理解出现的概念和问题。我还看到了一些关于 SO 的示例,但所有这些示例都需要访问生成线程的代码,或者使用传递给线程的共享互斥锁,或者使用 lockGuard

虽然我有一种无法逃避修改库代码的感觉,但我希望这有可能吗?

【问题讨论】:

  • “我怎样才能使输出同步?” 不能没有std::mutex 或其他与其他线程交互的同步机制,确保执行cout << "Writing file: " << "\n" << xmlFileName << endl; 原子地 AFAIK。
  • 为什么要写入标准输出?您可以使用一个适当的日志库,该库知道什么是完整的日志消息并且可以多线程工作。它还应该允许例如为每个日志条目添加一个线程 ID,以便更容易确定哪个部分属于哪个线程。
  • 我正在继承一个已有 5 年历史的遗留项目。实际上,作者想包括线程 ID 和信息,如下所示:#define screen cout << fixed << "["<< thread_id <<"]: " << name <<" [" <<control_loop_iteration << ", " << heterogeneous_controller << "]: " 但这会同样乱码,所以我完全省略了。你对这些图书馆有什么建议吗?我真的很想尽量减少第三方软件,尤其是看到我对 C++ 及其环境的了解。

标签: c++ multithreading boost synchronization cout


【解决方案1】:
  1. 你可能会变得非常hacky并编写一个同步流缓冲区。

    然后你可以在 cout 对象上使用它:

    std::cout.rdbuf(new my_sync_cout_buf());
    

    在开始线程之前。

    请注意,这将需要一些坐立不安才能以良好的方式响应刷新。如果(其中一个)线程随意使用std::unitbufstd::flush,这样做会崩溃。

    在绝对最坏的情况下,您必须打开线程 ID 并交错输出(例如逐行)

    THINKO:ostream 对象本身仍然是非线程安全的。所以这只是选项#2,真的:

  2. 也许从一个线程打开管道并从另一个线程读取它们更容易(也更明智)。这样,您可以自己协调输出完成的顺序。当然,由于您不控制线程,因此您必须 fork 而不是启动线程。

    然后,在每个子进程中,您可以设置std::cout的流缓冲区写入管道

【讨论】:

  • 实际上我使用了第一种方法,它对我有用——不是完美的,但足够了。原因是 IOStream 在很大程度上是无状态的,特别是没有需要线程安全分配的缓冲区,这些缓冲区位于流缓冲区中。现在,你不应该做的是使用例如像std::hex 这样的格式更改插入器,因为它们具有粘性并且可以跨线程操作。
  • @UlrichEckhardt 我意识到了这个漏洞。但我永远不会推荐它。我更愿意给出/直接/答案,但我意识到,如果你可以/证明/你使用iostream实例“as-if”const,你可以侥幸逃脱(这正是这条线首先产生选项 1. 的想法)。我希望你能明智地做事并取得成功:)
猜你喜欢
  • 2012-03-09
  • 1970-01-01
  • 2018-04-27
  • 1970-01-01
  • 2015-02-03
  • 2015-09-23
  • 1970-01-01
  • 1970-01-01
  • 2015-03-09
相关资源
最近更新 更多