首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >cout是同步的/线程安全的吗?

cout是同步的/线程安全的吗?
EN

Stack Overflow用户
提问于 2011-06-16 23:19:04
回答 1查看 41.5K关注 0票数 118

一般来说,我假设流是不同步的,这取决于用户是否进行适当的锁定。但是,像cout这样的东西在标准库中会得到特殊对待吗?

也就是说,如果多个线程正在向cout写入数据,它们会破坏cout对象吗?我知道即使同步了,你仍然会得到随机交错的输出,但是交错是有保证的吗?也就是说,从多个线程使用cout是否安全?

这个供应商是依赖的吗?gcc是做什么的?

重要提示:如果你说“是”,请为你的回答提供一些参考资料,因为我需要某种证明。

我也不关心底层的系统调用,这些都很好,但是流在上面增加了一层缓冲层。

EN

回答 1

Stack Overflow用户

发布于 2011-06-17 00:23:04

这是一个很好的问题。

首先,C++98/C++03没有“线程”的概念。因此,在那个世界里,这个问题是没有意义的。

那C++0x呢?看看Martinho's answer (我承认这让我很惊讶)。

C++0x之前的具体实现如何?好吧,举个例子,这里是来自GCC 4.5.2 ("streambuf“header)的basic_streambuf<...>:sputc的源代码:

代码语言:javascript
复制
 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使用的streambuf类型。

据我所知,libstdc++没有执行任何流操作的锁定。我不会期望任何东西,因为那会很慢。

因此,在这种实现中,很明显,两个线程的输出可能会相互损坏(而不仅仅是交错)。

这段代码会破坏数据结构本身吗?答案取决于这些函数可能的交互作用;例如,如果一个线程试图刷新缓冲区,而另一个线程试图调用xsputn或其他什么,会发生什么。这可能取决于编译器和CPU如何决定对内存加载和存储进行重新排序;这需要仔细分析才能确定。它还取决于当两个线程试图并发修改同一位置时CPU执行的操作。

换句话说,即使它碰巧在您当前的环境中运行良好,当您更新任何运行时、编译器或CPU时,它也可能会崩溃。

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

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

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6374264

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档