Order flows performed

Consider this simple match example:

#include <iostream> // std::cout #include <thread> // std::thread #include <mutex> // std::mutex std::mutex mtx; // mutex for critical section void print_block(int n, char c) { // critical section (exclusive access to std::cout signaled by locking mtx): mtx.lock(); for (int i = 0; i<n; ++i) { std::cout << c; } std::cout << '\n'; mtx.unlock(); } int main() { std::thread th1(print_block, 50, '*'); std::thread th2(print_block, 50, '$'); th1.join(); th2.join(); return 0; } 

Is it always guaranteed that th1 will be the first thread for the for loop?

Meaning when I do this:

 th1.join(); th2.join(); 

Then I can be absolutely sure that th1 will be executed first, and then th2 ?

+5
source share
1 answer

No, you most likely see that th1 always starts first, because building the stream for this variable first (and building the stream is expensive), so th2 starts after. This does not mean that there is order.

The join() call has nothing to do with which thread starts first, which is executed when building, when you provide the called one.

th1 can be constructed and then stopped by the OS, which will then start th2 . There is no order if you do not implement it.

Consider this example, which gives a much fairer start to both threads, sometimes it displays thread 1 as the first to get a lock, sometimes it gives thread 2.

Example:

 #include <iostream> // std::cout #include <string> // std::string #include <unordered_map> // std::unordered_map<K, V> #include <thread> // std::thread #include <mutex> // std::mutex #include <atomic> // std::atomic<T> std::unordered_map<std::thread::id, std::string> thread_map; std::mutex mtx; // mutex for critical section std::atomic<bool> go{ false }; void print_block( int n, char c ) { while ( !go ) {} // prevent threads from executing until go is set. // critical section (exclusive access to std::cout signaled by locking mtx): mtx.lock(); std::cout << thread_map.find( std::this_thread::get_id() )->second << " acquires the lock.\n"; mtx.unlock(); } int main() { std::thread th1( print_block, 50, '*' ); std::thread th2( print_block, 50, '$' ); thread_map.emplace( std::make_pair( th1.get_id(), "Thread 1" ) ); thread_map.emplace( std::make_pair( th2.get_id(), "Thread 2" ) ); go.store( true ); th1.join(); th2.join(); return 0; } 
+6
source

Source: https://habr.com/ru/post/1232900/


All Articles