Why are these threads not working in order?

When I run this code:

#include <iostream> #include <thread> #include <mutex> std::mutex m; int main() { std::vector<std::thread> workers; for (int i = 0; i < 10; ++i) { workers.emplace_back([i] { std::lock_guard<std::mutex> lock(m); std::cout << "Hi from thread " << i << std::endl; }); } std::for_each(workers.begin(), workers.end(), [] (std::thread& t) { t.join(); }); } 

I get the output :

 Hi from thread 7 Hi from thread 1 Hi from thread 4 Hi from thread 6 Hi from thread 0 Hi from thread 5 Hi from thread 2 Hi from thread 3 Hi from thread 9 Hi from thread 8 

Despite the fact that I used the mutex to only support one thread at a time. Why not clean up?

+7
c ++ multithreading c ++ 11
source share
4 answers

What your mutex achieves is that two streams are not printed at the same time. However, they are still racing, for which the thread first receives mutexes.

If you want to have serial execution, you can simply avoid threads at all.

+19
source share

It completely depends on the operating system in which order flows are planned. You cannot rely on any order. Suppose he is completely random.

+6
source share

You pass lambda to emplace_back, which is used as a parameter to the std :: thread constructor. See Details for emplace_back copy / ined below from cppreference.com.

"Adds a new element to the end of the container. The element is created using std :: allocator_traits :: construct, which usually uses the new location to create the element at the location indicated by the container. Args ... arguments are passed to the constructor as std :: forward (args). ... "

http://en.cppreference.com/w/cpp/container/vector/emplace_back

A mutex in a lambda body is not affected until the std :: thread object has been completely constructed and has completed the thread entry point defined by the lambda body. Some of the std :: threads may start during a loop, or threads may not start until the loop completes. You cannot figure it out figuratively.

After the for-loop builds all your std :: threads in your vector, it depends on the OS in which order the threads are planned, and that is how you get a random output order.

+3
source share

The execution order is not significant, you cannot predict it, and it will change from launch to launch and over time in this run.

Your projects should never depend on the flow order in any way or form.

This happens further: if N objects are waiting for a synchronization object, say, a mutex, and the mutexes are freed, there is no reliable and portable prediction of which of the waiting threads will be awakened and capture the mutex further, regardless of their relative planning priorities.

Non-determinism makes multithreaded programming difficult :-)

+2
source share

All Articles