If I'm synchronizing threads with join()
, considering the order of the calls to join, why do I sometimes see the output of t1
after t2
?
i.e.
#include <thread>
void callFromThread(int id) {
int i = 1000;
while(i != 0) {
printf("%s %d\n", "hi from thread", id);
i--;
}
}
int main(void) {
std::thread t1 (callFromThread, 1);
std::thread t2 (callFromThread, 2);
t1.join();
t2.join();
printf("%s\n", "bye from main!");
return 0;
}
I could make sense of the behaviour if I had some interleaving in the beginning before the join calls, followed by all remaining t1 outputs, followed by the remaining t2 outputs. But, instead I'm seeing all t2 then all t1, or vice-versa.
The C++ thread join is used to blocks the threads until the first thread execution process is completed on which particular join() method is called to avoid the misconceptions or errors in the code.
Join is a synchronization method that blocks the calling thread (that is, the thread that calls the method) until the thread whose Join method is called has completed. Use this method to ensure that a thread has been terminated.
no, you can detach one thread if you want it to leave it alone. If you start a thread, either you detach it or you join it before the program ends, otherwise this is undefined behaviour.
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. But this some point is non-deterministic.
join
affects the current thread you call join
, not the thread which is joined.
basically, join makes the current thread wait for another thread to finish execution. it has no effect on when the other thread is scheduled to run, or on what order compared to other threads.
in your example, there is no guarantee which of the thread t1
and t2
will run and finish first. the only guarantee is that the main thread waits for t1
first, then for t2
, then logs a message to stdout.
The order in which you join doesn't determine or influence the order in which the threads are executed. So, the output from both threads could be in any order (or interleaved).
The order of the calls doesn't mean that your output will be ordered the same way, and since you're executing the threads at "the same time" you can't control wich intruction is executed first in the CPU.
If you need to force that t1 make something before t2 just use Semaphores.
join
doesn't have any effect on the thread that it's applied to. It just blocks the thread that called it until the thread that it's applied to finishes, and then continues execution. So the order of calls to join
doesn't do anything to the order in which the threads are run.
Incidentally, in
std::thread t1(callFromthread, 1);
if (t1.joinable()) t1.join();
the test is redundant. Unless you call detach
, std::thread
objects are joinable.
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