The following code is from Dash
's example for std::thread
.
#include <iostream>
#include <thread>
#include <chrono>
void foo()
{
// simulate expensive operation
std::this_thread::sleep_for(std::chrono::seconds(1));
}
void bar()
{
// simulate expensive operation
std::this_thread::sleep_for(std::chrono::seconds(1));
}
int main()
{
std::cout << "starting first helper...\n";
std::thread helper1(foo);
std::cout << "starting second helper...\n";
std::thread helper2(bar);
std::cout << "waiting for helpers to finish..." << std::endl;
helper1.join();
// std::cout << "after join... \n";
helper2.join();
std::cout << "done!\n";
}
join blocks the current thread until the thread identified by *this finishes its execution.
Does thread execute after join
called?
If I add std::cout << "after join... \n"
after the first join, the after join...
and done!
will output sequentially, without delay, which just like being put after second join
.
To be specific, the whole effect is : print the first three lines sequentially without delay, then sleep for some while, final print the last two lines sequentially without delay.
a.join();
b.join();
cout << "something...";
// or
a.join();
cout << "something...";
b.join();
What confused me is : Why do the two ways have same effect? What does join
do exactly?
Joining a thread means waiting for it to terminate, which can be seen as a specific usage of condition variables. Using the pthread_join subroutine alows a thread to wait for another thread to terminate.
If you don't join these threads, you might end up using more resources than there are concurrent tasks, making it harder to measure the load. To be clear, if you don't call join , the thread will complete at some point anyway, it won't leak or anything.
Join method in Java allows one thread to wait until another thread completes its execution. In simpler words, it means it waits for the other thread to die. It has a void type and throws InterruptedException.
Your working threads will be in Terminated state (die) after join returns.
Both of your threads start at the same time and execute for the same length. Thus the join
in your case does not do much - both threads start at the same time and end at the same time.
As you can see printing anything before or after step 5 changes nothing.
A better example would be this:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
void foo()
{
// simulate expensive operation
cout << "Foo Start" << endl;
this_thread::sleep_for(chrono::seconds(1));
cout << "Foo Stop" << endl;
}
void bar()
{
// simulate expensive operation
cout << "Bar Start" << endl;
this_thread::sleep_for(chrono::seconds(2));
cout << "Bar Stop" << endl;
}
int main()
{
thread helper1(foo);
thread helper2(bar);
helper1.join();
cout << "Joined Foo... \n";
helper2.join();
cout << "Joined Bar... \n";
}
You will observe that if thread foo lasts for 1 second and thread bar for 2 seconds, then the "Joined Foo" and "Joined Bar" outputs will come with a 1 second delay in between. If you invert the durations to 2 seconds for foo and 1 second for bar, then the "Joined Foo" output will print after 2 seconds and "Joined Bar" immediately after that.
In one sentence, the joiner waits for the joinee to finish its execution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With