0

The main processes launches 4 threads. Now at this time all 4 threads will start execution immediately, but I want all the threads to wait till rest of all threads are also in running state.

I remember using a semaphore to track the thread counts, but not able to recall it. Is there any simple way to do without doing any busy-wait?

void *thread_routine(void *arg)
{
    // this thread should wait here till rest of all threads are also ready to run

    // do some job here

    return NULL;
}

int main(int argc, char *argv[])
{
    int i = 0;
    pthread_t thid[4];

    for (i = 0; i < 4; i++) {
        pthread_create(&tid[i], NULL, thread_routine, NULL);
    }

    for (i = 0; i < 4; i++) {
       pthread_join(tid[i], NULL);
    }
    return 0;
}
  • 2
    Think about just 2 threads, T1 and T2. If T1 waits for T2 to be running and T2 also waits for T1 to be running, then when will either start running? So, maybe clarify your issue. – Adrian Mole Sep 04 '22 at 13:41
  • 1
    Why do you want that? Whether or not a thread is "in running state" has no observable impact on your C program. Even if it is "in running state", there's no guarantee as to how much longer it might take to do any of the actual work it is supposed to do. Usually what you actually want is an indication when other threads have finished executing some specific code and made the results visible in memory. So this question sounds a lot like an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem/66378#66378). – Nate Eldredge Sep 04 '22 at 14:06
  • 2
    What do you think the difference is between four threads each starting to run when it is created and four threads each starting to run when it is informed it is time to start running? Blocking each thread for some signal to go will not reliably accomplish anything. It does not give you any more synchronization between threads than just creating them all does. – Eric Postpischil Sep 04 '22 at 14:41
  • Impossible unless the CPU has five or more cores and, unreliable anyway, no matter how attempted - essentially 'what Eric says':) – Martin James Sep 04 '22 at 16:10
  • @AdrianMole For example, say all threads (2 or more), needs to participate in a game. So before the game begins I want to make sure that all threads are created by MAIN and are in running state. I do not want a situation where as soon as 1st thread is created, it starts the game because rest of threads might still not be created yet. I will later synchronize the threads (using mutexes and condition variables) based on the rules of the game. Hope this clarifies my requirement. – Abdul Ansari Sep 04 '22 at 17:29
  • @NateEldredge Please look at my comment for more details about my requirement. – Abdul Ansari Sep 04 '22 at 17:33
  • @EricPostpischil Please look at my comment for more details about my requirement. I think the Answer which I got below to use PTHREAD_BARRIER_WAIT is what I need. Thanks. – Abdul Ansari Sep 04 '22 at 17:35
  • 2
    @AbdulAnsari: Having all the threads wait for a barrier and then become runnable does not guarantee that the threads will actually run. It will still be possible for one of them to run and to start the game while the others are runnable but not actually running. If you need to synchronize some resource use between the threads, you need to use something more specific than a barrier wait. If you are trying synchronize execution of multiple threads, you need real-time performance guarantees from the operating system. – Eric Postpischil Sep 04 '22 at 18:08
  • 1
    @AbdulAnsari: No, that doesn't answer my question. *Why* do you think you need to wait for the other threads to be created? What actions do you think it would be safe to take after that point, which it wouldn't be safe to do earlier? If you really do have proper synchronization elsewhere, then it would take care of any necessary blocking. If you don't, then your code is racy, and "waiting for a thread to be created" won't eliminate the race. – Nate Eldredge Sep 04 '22 at 18:29
  • @EricPostpischil Can you please explain how can I achieve this requirement. I just want all threads to have been created and become runnable. How can I achieve this? I think waiting on PTHREAD_BARRIER_WAIT (for count = NUM_THREADS) will make sure that all threads will hit the barrier once and then game can begin. I understand that threads can still go back to WAIT/BLOCK state but that is part of the game which I need to handle synchronize them to complete the game. If you have better deterministic solution please share. Thanks. – Abdul Ansari Sep 04 '22 at 19:17
  • @NateEldredge I understand any solution which requires assumption like this to have all threads running is not ideal. But if you look at my requirement then you will acknowledge why I need this. The game which these threads will play is say 'ROLL A DICE' in a loop where each loop represents 1 round of game. And I want the MAIN thread to decide the winner (maximum dice value) and declare it before the next round of rolling dice begins. And this continues for a chosen number of rounds. – Abdul Ansari Sep 04 '22 at 19:27
  • So then what you need is not merely that the other threads have *become runnable*, but that they have all *finished* rolling their respective dice and made the results ready for the main thread to use. ("Finished" in the sense of "happens before", in order to avoid data races.) – Nate Eldredge Sep 04 '22 at 19:33

1 Answers1

1

What you describe sounds like barrier synchronization which can be implemented using pthread_barrier_wait.

Here's a simple example using it (from TLPI book).

P.P
  • 117,907
  • 20
  • 175
  • 238
  • Stack Overflow answers should provide all the information needed to understand (and, preferably, to implement) the answer in the posted answer itself, not as links to external sites. External sites change and vanish. They can serve as supplemental information but not as durable answers. – Eric Postpischil Sep 04 '22 at 17:59
  • 1
    @EricPostpischil "Stack Overflow answers should provide all the information needed to understand" - I clearly didn't get that memo. "Use pthread_barrier_wait" is all there is (the links are just supplementary) which should be enough for "professional and enthusiast programmers" to do their own reading and research. Spoon-feeding isn't my strong suit. Feel free. – P.P Sep 04 '22 at 18:52