我想用一个例子说明我的问题。
假设有一组N /*(N>>1)*/
线程设置为运行此函数:
void Process() {
//Some thread safe processing which requires in-deterministic computation time
unsigned char byte;
std::cin >> byte;
}
一旦所有这些同时启动,会发生什么?如何处理并发的std :: cin访问?在控制台上操作的最终用户会看到什么?
编辑:还有一件事我想补充。下面的代码是否安全到足以放弃仅在一个(可能是主)线程中使用std:cin的想法?
void Process() {
//Some thread safe processing which requires in-deterministic computation time
//Mutex lock
unsigned char byte;
std::cin >> byte;
//Mutex unlock
}
在C ++ 11之前的版本中,取决于实现方式;至少一种实现方式保证了呼叫的同步。(VC ++保证的同步std::cout
,但不保证其他iostream对象的同步。g ++提供与C ++ 11相同的保证,即使在较早版本的编译器中也是如此。)在C ++ 11中,它是明确未定义的行为。
通用规则很简单:任何线程中对象状态的任何修改都要求所有访问都必须同步。并且所有>>
操作符std::istream
都被认为可以修改其状态。
更一般而言,对于任何特定的流,最好仅在一个线程中使用它。(有一些例外,例如日志记录流,其中日志记录对象确保线程安全。)对于输入尤其如此,因为即使在外部同步时,如果操作符位于单独的线程中,通常也不会指定操作符的顺序。因此,即使进行了同步,如果用户输入"ab"
,示例中的哪个线程'a'
和哪个线程'b'
也将不确定。
似乎有成为标准的流对象(特殊规则std::cin
,std::cout
等等)。至少在某些情况下,保证并发访问不会产生数据争用。它仍然可能导致字符混合,即:如果您正在输入int
(而不是单个字符),并且您的用户输入了"123 89\n"
,则线程1"1389\n"
和线程2可能会看到"2 "
,这不会给您带来连贯的结果。
我的全球建议不变。我想不出任何现实的情况,字符的交织不会造成问题。(此外,我认为我从未写过实际上是从那里输入的代码std::cin
;它总是来自std::istream&
可能是std::cin
或可能是文件的输入。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句