我想用一个例子说明我的问题。
假设有一组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
}
答案 0 :(得分:9)
我想说,没有互斥体,结果是不可预测的。
如果使用互斥锁,一切都很好。这就是互斥体的用途。
答案 1 :(得分:5)
第一个线程使用std :: cin锁定它(除非你use sync_with_stdio(false)
)。所以,你不需要互斥锁。
http://en.cppreference.com/w/cpp/io/cin
无论如何,我不建议在多线程应用程序中使用它。
问题是没有办法从其他线程中断cin输入。
答案 2 :(得分:5)
Pre 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
,也可能是{{1}}
一个文件。)