C++ 中的标准输出流是线程安全的(cout、cerr、clog)吗?
Posted
技术标签:
【中文标题】C++ 中的标准输出流是线程安全的(cout、cerr、clog)吗?【英文标题】:Are standard output streams in C++ thread-safe (cout, cerr, clog)? 【发布时间】:2010-12-01 18:56:03 【问题描述】:我知道目前C++
没有线程的概念,但是this article is saying:
类型安全、线程安全、可移植 日志记录机制
.....
fprintf()
函数是线程安全的, 所以即使这个日志是从 不同的线程,输出线 不会乱码。
cout
、cerr
和 clog
呢?
我认为这个问题也适用于 C++ 中的所有类型的流类型,例如 fstream
和 stringstream
。
【问题讨论】:
Note: the answer is now "yes", in C++11. @GManNickG:我使用 Visual Studio 2013 C++,但 cout 仍然不是线程安全的。屏幕上的输出大多已损坏/混合。 @MehmetFide:线程安全不同于同步(混合/交错字符串); C++11 标准保证,在使用来自不同线程的这些对象时,实现不会导致数据竞争,而您可以确保多个operator<<
调用是同步的。
【参考方案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++ 标准甚至不承认存在称为“线程”的东西,因此它当然根本没有提供任何关于线程安全的保证。
这都是实现定义的。
【讨论】:
以上是关于C++ 中的标准输出流是线程安全的(cout、cerr、clog)吗?的主要内容,如果未能解决你的问题,请参考以下文章
c++语言中的标准输入输出用cin和cout表示,请问名字中的'c'表示啥?