Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I wait for any/all pthreads to complete?

I just want my main thread to wait for any and all my (p)threads to complete before exiting.

The threads come and go a lot for different reasons, and I really don't want to keep track of all of them - I just want to know when they're all gone.

wait() does this for child processes, returning ECHILD when there are no children left, however wait does not (appear to work with) (p)threads.

I really don't want to go through the trouble of keeping a list of every single outstanding thread (as they come and go), then having to call pthread_join on each.

As there a quick-and-dirty way to do this?

like image 840
Brad Avatar asked May 27 '11 15:05

Brad


People also ask

How are pthreads scheduled?

Scheduling. You use the Pthreads scheduling features to set up a policy that determines which thread the system first selects to run when CPU cycles become available, and how long each thread can run once it is given the CPU.

Do pthreads run on different cores?

It can run them on multiple CPUs if it so decides. In doing so, it causes the user space threads mapped to such kernel threads to run on these CPUs as well. This can be seen in many systems in fact.

What is meant by pthreads?

Portable Operating System Interface for Computer Environments (POSIX) is an interface standard governed by the IEEE and based on UNIX®.


2 Answers

Do you want your main thread to do anything in particular after all the threads have completed?

If not, you can have your main thread simply call pthread_exit() instead of returning (or calling exit()).

If main() returns it implicitly calls (or behaves as if it called) exit(), which will terminate the process. However, if main() calls pthread_exit() instead of returning, that implicit call to exit() doesn't occur and the process won't immediately end - it'll end when all threads have terminated.

  • http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_exit.html

Can't get too much quick-n-dirtier.

Here's a small example program that will let you see the difference. Pass -DUSE_PTHREAD_EXIT to the compiler to see the process wait for all threads to finish. Compile without that macro defined to see the process stop threads in their tracks.

#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <time.h>  static void sleep(int ms) {     struct timespec waittime;      waittime.tv_sec = (ms / 1000);     ms = ms % 1000;     waittime.tv_nsec = ms * 1000 * 1000;      nanosleep( &waittime, NULL); }  void* threadfunc( void* c) {     int id = (int) c;     int i = 0;      for (i = 0 ; i < 12; ++i) {         printf( "thread %d, iteration %d\n", id, i);         sleep(10);     }      return 0; }   int main() {     int i = 4;      for (; i; --i) {         pthread_t* tcb = malloc( sizeof(*tcb));          pthread_create( tcb, NULL, threadfunc, (void*) i);     }      sleep(40);  #ifdef USE_PTHREAD_EXIT     pthread_exit(0); #endif      return 0; } 
like image 185
Michael Burr Avatar answered Sep 30 '22 17:09

Michael Burr


The proper way is to keep track of all of your pthread_id's, but you asked for a quick and dirty way so here it is. Basically:

  • just keep a total count of running threads,
  • increment it in the main loop before calling pthread_create,
  • decrement the thread count as each thread finishes.
  • Then sleep at the end of the main process until the count returns to 0.

.

volatile int running_threads = 0; pthread_mutex_t running_mutex = PTHREAD_MUTEX_INITIALIZER;  void * threadStart() {    // do the thread work    pthread_mutex_lock(&running_mutex);    running_threads--;    pthread_mutex_unlock(&running_mutex); }  int main() {   for (i = 0; i < num_threads;i++)   {      pthread_mutex_lock(&running_mutex);      running_threads++;      pthread_mutex_unlock(&running_mutex);      // launch thread    }    while (running_threads > 0)   {      sleep(1);   } } 
like image 44
gravitron Avatar answered Sep 30 '22 15:09

gravitron