【问题标题】:Are standard output streams in C++ thread-safe (cout, cerr, clog)?C++ 中的标准输出流是线程安全的(cout、cerr、clog)吗?
【发布时间】:2010-12-01 18:56:03
【问题描述】:

我知道目前C++没有线程的概念,但是this article is saying

类型安全、线程安全、可移植 日志记录机制

.....

fprintf() 函数是线程安全的, 所以即使这个日志是从 不同的线程,输出线 不会乱码。

coutcerrclog 呢?

我认为这个问题也适用于 C++ 中的所有类型的流类型,例如 fstreamstringstream

【问题讨论】:

  • @GManNickG:我使用 Visual Studio 2013 C++,但 cout 仍然不是线程安全的。屏幕上的输出大多已损坏/混合。
  • @MehmetFide:线程安全不同于同步(混合/交错字符串); C++11 标准保证,在使用来自不同线程的这些对象时,实现不会导致数据竞争,而您可以确保多个 operator<< 调用是同步的。

标签: c++ thread-safety iostream


【解决方案1】:

这篇文章对fprintf API 的POSIX 标准提出了声明。它没有说明 C++ 流。这是完全正确的,因为这些流上没有这样的保证。

请注意,尽管该文章中的日志记录类使用 C++ 流语法,但它通过为每个日志记录事件创建和销毁的 std::ostringstream 对象来执行此操作,因此不会在线程之间共享。它使用fprintf 将内容实际写入控制台。

Microsoft C 库声称与 POSIX 兼容,因此本文中的代码可能具有相当广泛的可移植性(因为许多其他流行的操作系统都与 POSIX 兼容)。但这并不意味着标准 C++ 流是线程安全的。

【讨论】:

    【解决方案2】:

    这将是特定于实现的细节。您可以询问具有运行时库 Y 的编译器 X 是否具有线程安全的标准流,但您不能询问是否所有实现都有,因为允许实现在线程安全方面有所不同。这是 C++ 没有内置线程概念的部分含义。它是所有特定于实现的。

    【讨论】:

    • 我也是这么想的 :) 但是文章声称代码也是可移植的!
    • 我猜这篇文章的作者只是说它在他尝试过的任何地方都有效。他可能没有尝试过,比如 Keil C 和 HomeGrownRTOS v1.2,或任何其他不常见的组合。
    • 这篇文章不是在讨论 C++ 流。
    • @Warren Young - 文章的作者并不是那么愚蠢,事实上。他们特别说明了他们的代码必须支持什么标准才能工作。
    • @Earwicker,我认为这与是否愚蠢无关。作者声称它是可移植的 posix 代码。纯 C 函数 fprintf 仍然不是线程安全的。
    【解决方案3】:

    由于当前的 C++ 标准甚至不承认存在称为“线程”的东西,因此它当然根本没有提供任何关于线程安全的保证。

    这都是实现定义的。

    【讨论】:

      猜你喜欢
      • 2011-01-16
      • 2013-01-16
      • 2011-01-25
      • 2011-04-16
      • 2013-11-27
      • 2021-03-20
      • 1970-01-01
      • 2023-03-10
      • 2013-08-23
      相关资源
      最近更新 更多