5

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?

Yann
  • 978
  • 2
  • 12
  • 31
  • 1) [`joinable`](http://en.cppreference.com/w/cpp/thread/thread/joinable) doesn't mean what you think it means. 2) Execution order is not influenced by join order – Stephan Dollberg Sep 24 '14 at 10:14
  • The threads will execute in parallel. `join` simply means "block until the associated thread completes", and the order in which you join the threads doesn't affect execution order. – T.C. Sep 24 '14 at 10:15
  • So if I run through and `join()` each thread in a for loop like I have there, it will run 'properly'? – Yann Sep 24 '14 at 10:17
  • @bamboon Thanks, I wasn't sure whether it was just my perception of the order of execution or the actual order changing, ta for the clarification. – Yann Sep 24 '14 at 10:21

2 Answers2

3

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.

Community
  • 1
  • 1
Stephan Dollberg
  • 32,985
  • 16
  • 81
  • 107
1

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.