I have a simple application with a "manager" thread that spawns ten simple "worker" threads. I want all of the "worker" threads to block on the same condition variable (ie: condvar), and I want to manually signal all ten threads to wake up at the same time with a pthread_cond_broadcast call.
In the case of my application, it is possible for threads to suffer an error condition and terminate early, so it is possible that not all ten threads make it to the synchronization point.
One simple mechanism would be to create a pthread_barrier_t and have all ten threads call pthread_barrier_wait, and when all ten threads complete this call, they are all free to continue execution. However, this would require the threads being able to modify the number of threads the barrier requires to unblock. I don't know if this can be safely modified.
Additionally, I want to guarantee all the still-working threads not start automatically like they would with a barrier, I want to manually start them with a pthread_cond_broadcast call instead. How would I guarantee that all the threads that are still alive (ideally ten) have blocked on the condvar before I made the broadcast call?
Thanks!
The following shows one way to do it, using a condition variable and a few other variables; though there may be better ways. The comments should show how it works. You'd have to modify things to suit your actual situation of course; for instance there might be loops involved, etc.
I'd add, though, that I don't see when there'd be a good reason to do this rather than just protecting resources in a more straightforward way.
EDIT: Added some things to the code, showing a second condition variable used to let the main thread wait for all the workers to be ready. The changed parts are marked with "EDIT:" in comments, and can be left out if not needed. I've also corrected a race condition by moving the increment of
activeThreads
out of the thread function, and shown the initialization for the mutex, etc. (without error handling).Generally speaking, you should just set the condition variable (and it's associated flag) when the work is ready to go - there's usually no need to wait for the threads to block on the condition var. If they're 'late', they'll just notice that the flag is already set and not bother blocking.
But if you really do need to wait until all worker threads are at the point where they're cloking on the condition var, you can use a combination of condition variables - one that tracks how many threads are 'ready to go' and the other trigger them to start work. Some peudo code:
Of course, the pseudo-code presented should be cleaned up for any real use (including error handling), probably packaging all the supporting condition variables, mutex, and flags into a structure