Reputation: 27
So I have been recently trying to wrap my head around multithreading and understand how it works. I have some example code here but I cannot understand why the output is the way it is.
Example code:
#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
using namespace std;
std::mutex mtx;
int global_counter = 0;
std::mutex counter_mutex;
void five_thread_fn(){
for(int i = 0; i<5; i++){
counter_mutex.lock();
global_counter++;
std::cout << "Updated from five_thread" << endl;
counter_mutex.unlock();
// std::this_thread::sleep_for(std::chrono::seconds(5));
}
//When this thread finishes we wait for it to join
}
void ten_thread_fn(){
for(int i = 0; i<10; i++){
counter_mutex.lock();
global_counter++;
std::cout << "Updated from ten_thread" << endl;
counter_mutex.unlock();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
//When this thread finishes we wait for it to join
}
int main(int argc, char *argv[]) {
std::cout << "starting thread ten..." << std::endl;
std::thread ten_thread(ten_thread_fn);
std::cout << "Starting thread five..." << endl;
std::thread five_thread(five_thread_fn);
five_thread.join();
std::cout << "Five Thread is done." << std::endl;
ten_thread.join();
std::cout << "Ten Thread is done." << std::endl;
// std::cin.ignore();
return 0;
}
I have commented out the time delays in the threads and here is my output:
Starting thread ten...
Starting thread five...
Updated from five_thread
Updated from ten_thread
Updated from five_thread
Updated from five_thread
Updated from five_thread
Updated from five_thread
Five Thread is done.
Updated from ten_thread
Updated from ten_thread
Updated from ten_thread
Updated from ten_thread
Updated from ten_thread
Updated from ten_thread
Updated from ten_thread
Updated from ten_thread
Updated from ten_thread
Ten Thread is done.
Now I am wondering why does "updated from ten_thread" appear after the first line of "updated from five_thread"?
In the main function when I do
five_thread.join();
Does that not suspend the main thread until five_thread completes its execution?
To my understanding, it is only after the five_thread finishes that the lines after five_thread.join() execute (sequentially). So how is the ten_thread being called in between?
Is the execution of the lines of code in main() not sequential?
Upvotes: 1
Views: 580
Reputation: 473447
Does that not suspend the main thread until five_thread completes its execution?
Yes. But the fact that A is waiting on B does not somehow stop C from doing its own thing on its own time. Joining a thread does not give that thread priority in terms of execution. It doesn't mean that the thread being joined will start at that point.
Concurrent execution means concurrent execution. There is no order between the execution of concurrent things unless you explicitly give it one. Joining a thread only states that the current thread will resume after the given one has completed.
Upvotes: 1
Reputation: 118340
To my understanding, it is only after the five_thread finishes that the lines after five_thread.join() execute (sequentially). So how is the ten_thread being called in between?
Because that thread has already been started.
std::thread ten_thread(ten_thread_fn);
This starts the execution thread. ten_thread()
is not being called "in between" of anything. It is an independent execution thread, that executes concurrently with all other threads.
The thread gets started when std::thread
gets instantiated, and continues executing while the main thread goes along its business.
All that join()
does is pause the main execution thread until the given execution thread terminates. That execution thread is already running, concurrently.
As soon as ten_thread
gets instantiated, it means that ten_thread_fn()
is executing, loosely speaking.
Upvotes: 1