What are the different ways of ensuring that a bunch of pthreads
all start at the same time?
I could find only one way, ie. initializing a barrier
in the main thread, then waiting on it in the newly created pthreads.
What are the different ways of ensuring that a bunch of pthreads
all start at the same time?
I could find only one way, ie. initializing a barrier
in the main thread, then waiting on it in the newly created pthreads.
That's pretty much exactly how I've done it in the past.
main:
claim mutex
for each desired thread:
start child
release mutex
:
child:
claim mutex
release mutex
:
Note that this doesn't actually guarantee that all the threads have started before the first one starts doing something, just that the main thread has created them.
In order to do that, you can use something like the following method:
main:
claim mutex
set unstarted to 0
for each desired thread:
start child
add 1 to unstarted
release mutex
:
child:
claim mutex
subtract 1 from unstarted
while unstarted > 0:
release mutex
yield // if necessary
claim mutex
release mutex
:
Whatever initialisation a thread has to do to be considered started will occur between the claim
and the subtract
.
I see from further investigation that barriers are actually a more elegant way to do this. They weren't actually available in the pthread implementations I used which is why my code may seem a little verbose.
However, I'll leave it as-is on the off-chance that someone uses pre-v6 pthreads or a different threading method (without barriers) and because, as the question asked, this is a different way of doing it.
You can use pthread_cond_broadcast
. They won't be launched completely simultaneously because of the mutex. You could try to use a different mutex for each thread, but using different mutexes for the same condition variable is undefined.
#include <pthread.h>
pthread_mutex_t join_mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void thread_function (void *param) {
pthread_mutex_lock(&join_mut);
pthread_cond_wait(&cond, &join_mut);
pthread_mutex_unlock(&join_mut);
/* Thread work here */
}
enum { threads = 16 };
int main() {
int i;
pthread_t thread_table[threads];
for(i = 0; i < threads; i++) {
pthread_create(&(thread_table[i]), NULL, thread_function, NULL);
}
/* Wait for all threads to be queued */
pthread_cond_broadcast(&cond);
}