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?
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.
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.
Portable Operating System Interface for Computer Environments (POSIX) is an interface standard governed by the IEEE and based on UNIX®.
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.
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; }
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:
.
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); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With