Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread join c++ behaviour

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.

like image 562
wulfgarpro Avatar asked Aug 11 '16 10:08

wulfgarpro


People also ask

What does thread join do C?

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.

What happens when a thread is joined?

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.

Do you have to join threads in C?

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.

What happens if you don't join a thread in C?

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.


4 Answers

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.

like image 103
David Haim Avatar answered Oct 20 '22 23:10

David Haim


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).

like image 20
P.P Avatar answered Oct 20 '22 23:10

P.P


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.

like image 35
Raskayu Avatar answered Oct 20 '22 23:10

Raskayu


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.

like image 1
Pete Becker Avatar answered Oct 20 '22 22:10

Pete Becker