Yann
Yann

Reputation: 988

Joining multiple threads in any order

I have an array of std::thread objects that it doesn't matter what order they operate in and what order they rejoin the main thread. I've tried using

for(int i = 0; i < noThreads; ++i)
{
    if(threads[i].joinable())
        threads[i].join();
}

but that seems to make them operate "in order", of course that could be the fact that i'm reaching that conclusion from the fact that the console output from the threads is happening in the order that I dispatch them in (as in all of the output from thread #1 then all of the output from thread #2). I have also attempted threads[i].detach(), but I don't know the execution time of each thread, so I can't pause the program until they have finished.

The work that each thread is doing is:

int spawn(const char* cmd)
{
    FILE *fp = popen(cmd, "r");

    char buff[512];

    if(vFlag == 1)
    {
        while(fgets(buff, sizeof(buff), fp)!= NULL)
        {
            printf("%s", buff);
        }
    }

    int w = pclose(fp);
    if(WIFEXITED(w))
        return WEXITSTATUS(w);
    else 
        return -1;
}

where the command being executed is "./otherApp.elf". Bearing in mind that the current fact that it is being printed out to console will change to being output to various files, how do I dispatch the threads so that I can make them execute then rejoin out of order?

Upvotes: 5

Views: 5023

Answers (2)

Stephan Dollberg
Stephan Dollberg

Reputation: 34608

Execution order is not influenced by join order. So you can simply call join in a loop to join all the threads.

A second thing worth pointing out is that joinable doesn't mean whether a thread has finished execution. See the link for a detailed explanation.

If you really want to check whether a thread has finished execution there might be other ways to do it as described here.

Boost already has extensions to wait for any or all of a set of futures and testing functions to see whether a thread has finished execution.

Upvotes: 4

Stefano Falsetto
Stefano Falsetto

Reputation: 572

The for cycle you are using is giving you the order of joining (NOT the threads execution order).

I mean that the join function is blocking the process in waiting for the thread to complete, so if you check the threads with the for cycle you're using, you'll block your main process on the first join even if (i.e.) the last thread is already finished.

As you can see i.e. here, the joinable method is meaning something like: is this thread started (or maybe finished) and not already joined?

So if you need to know if a thread is finished, I think you can use something like a semaphore linked to each thread and check its value in a cycle. So you'll not block the main process and you'll join threads almost in their finishing order.

Upvotes: 1

Related Questions