正如C标准提到的:
多个线程并发访问同步(29.5.3.5)标准iostream对象的格式化和非格式化输入(29.7.4.2)和输出(29.7.5.2)函数或标准C流不会导致数据争用(6.9.2)。
[Note 1:多个线程不同步地并发使用这些对象和流可能会导致字符交错。-end note]
所以如果我理解正确的话,Note 1的意思是,如果我并发访问一个同步的标准iostream对象(使用sync_with_stdio(true)
),就不会有交错字符,比如我有2个线程,其中一个使用cout输出123
,另一个使用cout输出456
,那么我可以得到123456
或456123
,但不能得到142536
。
我的理解是正确的吗?如果是正确的,那么你能指出C是如何实现的吗?以gcc为例,我检查了gcc代码,cout只是ostream的一个示例,ostream::sentry并没有包含一个锁来保护输出,cout的流缓冲区只是把字符一个一个地放到底层的标准输出文件中。那么系统如何确保字符不交错?
多谢了!
2条答案
按热度按时间mwg9r5ms1#
注1意味着如果我并发访问一个同步的标准
iostream
对象,将不会有交错字符不,注解指出,虽然没有争用,但可能会出现交错字符--所以,与您的结论完全相反。
sync_with_stdio(true)
并不意味着“线程同步”,如“无论有多少线程使用它,每次一行”。它是关于cout
/cin
和底层C流之间的同步。到cout
的输出立即应用于例如stdout
C流。C++如何避免
cout
的交错字符?我想您可能会想知道如何确保在多线程中使用
cout
时不会出现交错字符,如果是这样,请同步使用cout
,您可以使用std::mutex
来实现这一点。2fjabf4q2#
第一段意味着流必须处理并发访问(也就是说,它们必须永远不会崩溃),并且所有字节都将以未指定的顺序写入。
第二段澄清了它们可以而且经常会交叉字符。