如何scanf(),std :: cin行为在多线程环境? [英] How do scanf(), std::cin behave on multithreaded environment?

查看:1627
本文介绍了如何scanf(),std :: cin行为在多线程环境?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用一个例子说明我的问题。

I'd like to state my problem using an example.

假设有一个数组 N / *(N& 1)* / 线程设置为运行此函数:

Assuming there is an array of N /*(N>>1)*/ threads which are set to run this function:

void Process() {
    //Some thread safe processing which requires in-deterministic computation time

    unsigned char byte;
    std::cin >> byte;
}

一旦所有这些都同时启动,会发生什么?如何处理并发的std :: cin访问?在控制台上操作的最终用户如何看到/体验?

Once all of them are started simultaneously, what does happen? How are concurrent std::cin accesses handled? What does the end-user who operates on console see/experience?

编辑:还有一件事我想添加。下面的代码是否足够安全,放弃了在一个(可能是主线程)线程中使用std:cin的想法?

There is one more thing I'd like to add. Is the code below safe enough to abandon the idea of using std:cin only in one (probably main) thread?

void Process() {
    //Some thread safe processing which requires in-deterministic computation time

    //Mutex lock
    unsigned char byte;
    std::cin >> byte;
    //Mutex unlock
}


推荐答案

p> Pre C ++ 11,这取决于实现;至少一个
实现保证调用的同步。 (VC ++
保证了 std :: cout 的同步,而不是其他
iostream对象的同步g ++提供与C ++ 11相同的保证,
即使在早期版本的编译器中。)在C ++ 11中,它是
显式未定义的行为。

Pre C++11, it depends on the implementation; at least one implementation guaranteed synchronization of the calls. (VC++ guarantees the synchronization of std::cout, but not for other iostream objects. g++ offers the same guarantees as C++11, even in earlier versions of the compiler.) In C++11, it is explicitly undefined behavior.

一般规则很简单:任何线程中
对象的状态的任何修改都要求所有访问被同步。
并且 std :: istream 上的所有>> 运算符被视为
修改它的状态。

The general rule is simple: any modification of state of an object in any thread requires all accesses to be synchronized. And all >> operators on std::istream are considered to modify its state.

更一般地说,对于任何特定的流,它可能是一个好的
策略,只使用它在一个线程。 (有例外,
例如日志流,其中日志对象确保线程
安全。)这对输入尤其如此,因为即使
在外部同步,操作符的排序将
一般不指定,如果他们在不同的线程。所以
即使同步,如果你的用户输入ab,其中
线程得到'a',并且在您的示例中获取'b'将是
未定。

More generally, for any particular stream, it is probably a good policy to use it in only one thread. (There are exceptions, such as logging streams, where the logging object ensures thread safety.) This is especially true of input, since even when synchronized externally, the sequencing of the operators will generally be unspecified if they are in separate threads. So even with synchronization, if your user inputs "ab", which thread gets 'a' and which gets 'b' in your example would be undetermined.

似乎有标准流对象的特殊规则
std :: cin std :: cout 等)。并发访问是
保证不产生数据竞赛,至少在某些情况下。
它仍然可能导致字符混合,即:如果你是
输入 int (而不是单个字符),而你的用户
输入123 89 \\\
,线程1可能会看到
1389 \\\
和线程2 2,这将不会给出连贯的
结果。

There seem to be special rules for the standard stream objects (std::cin, std::cout, etc.). Concurrent access is guaranteed not to produce a data race, at least in some cases. It may still result in characters being mixed, i.e.: if you're inputing int (rather than a single character), and your user inputs "123 89\n", there's a possibility that thread 1 will see "1389\n", and thread 2 "2 ", which won't give you coherent results.

我的全球推荐。我不能想到任何现实的
情况,其中字符的交错不会创建
一个问题。 (另外,我不认为我曾经写过代码
实际上从 std :: cin 输入;它总是从
std :: istream& 这可能是 std :: cin ,或者可能是
a文件。)

My global recommendation stands. I can't think of any realistic case where the interleaving of characters wouldn't create a problem. (Also, I don't think I've ever written code which actually inputs from std::cin; it's always from an std::istream& which might be std::cin, or might be a file.)

这篇关于如何scanf(),std :: cin行为在多线程环境?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆