问题
I'd like to state my problem using an example.
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;
}
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?
Edit: 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
}
回答1:
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.
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.
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.
EDIT:
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.
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.)
回答2:
I would say, the result is not predictable without mutexes.
If you use a mutex, everything is fine. That's what mutexes are for.
回答3:
The first thread uses std::cin locks it (Unless you use sync_with_stdio(false)). So, you don't need a mutex.
http://en.cppreference.com/w/cpp/io/cin
Anyway I don't recommend to use it in multi-thread application.
The problem is there's no way to interrupt cin input from other thread.
来源:https://stackoverflow.com/questions/18844239/how-do-scanf-stdcin-behave-on-multithreaded-environment