为了账号安全,请及时绑定邮箱和手机立即绑定

cout同步/线程安全吗?

cout同步/线程安全吗?

C++
手掌心 2019-06-26 17:11:41
cout同步/线程安全吗?一般来说,我假设流不是同步的,应该由用户来执行适当的锁定。然而,做这样的事情cout在标准图书馆得到特殊待遇?也就是说,如果多个线程正在写入cout他们能把cout反对?我知道,即使同步,您仍然会得到随机交错的输出,但这种交织是有保证的。也就是说,使用起来安全吗?cout从多个线程?这个供应商依赖吗?GCC是做什么的?重要:如果你说“是”,请提供一些参考,因为我需要一些证据。我还担心的不是底层的系统调用,它们很好,但是流在顶部添加了一层缓冲。
查看完整描述

3 回答

?
茅侃侃

TA贡献1842条经验 获得超21个赞

这是个很好的问题。

首先,C+98/C+03没有“线程”的概念。所以在这个世界上,这个问题是毫无意义的。

那C+0x呢?看见Martinho的回答(我承认这让我很惊讶)。

具体的实现前C+0x怎么样?例如,下面是basic_streambuf<...>:sputcGCC 4.5.2(“流线型”头球):

 int_type
 sputc(char_type __c)
 {
   int_type __ret;
   if (__builtin_expect(this->pptr() < this->epptr(), true)) {
       *this->pptr() = __c;
        this->pbump(1);
        __ret = traits_type::to_int_type(__c);
      }
    else
        __ret = this->overflow(traits_type::to_int_type(__c));
    return __ret;
 }

显然,这不执行锁定。也没有xsputn..这绝对是cout使用的流的类型。

据我所知,libstdc+不对任何流操作执行锁定。我不希望有,因为那会很慢。

因此,使用此实现,两个线程的输出显然有可能相互损坏(只是交错)。

这个代码会破坏数据结构本身吗?答案取决于这些函数的可能交互;例如,如果一个线程试图刷新缓冲区,而另一个线程试图调用xsputn或者别的什么。这可能取决于编译器和CPU如何决定重新排序内存负载和存储;需要仔细分析才能确定。如果两个线程试图并发地修改同一个位置,则还取决于CPU所做的工作。

换句话说,即使它在当前环境中正常工作,当您更新任何运行时、编译器或CPU时,它也可能中断。

执行摘要:“我不会”。构建一个日志类来执行正确的锁定,或者移动到C+0x。

作为一个弱的替代方案,您可以将cout设置为未缓冲。可能会跳过与缓冲区和调用相关的所有逻辑(尽管没有保证)。write直接。尽管这可能会令人望而却步。


查看完整回答
反对 回复 2019-06-26
  • 3 回答
  • 0 关注
  • 674 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信