I am implementing a thread pool. The work required by each thread is 1-10 seconds of CPU, so I'm happy to have a traditional thread pool with workers, or I'm happy to spawn a new thread for each unit of work. It doesn't matter.
I would like to have some way for the master control thread to know when one of the N worker threads finishes its work and is ready for more (or its time to start another). I've looked at pthread_join and pthread_cond_wait. There doesn't seem to be a way to wait for one of N. So I thought a开发者_StackOverflow中文版bout having the master thread have a variable that it uses to go to sleep and having the workers wake it up. This seems to work if the workers don't die. However, if they die, there's a window between the time that the worker wakes up the controller and the time it dies which I don't want to deal with.
I've looked at Intel's TBB but it looks much more complicated than I need.
Is there a simple equivalent in PTHREADS to WaitForMultipleObjects in Microsoft Windows?
This is a reasonably simple use case for condition variables.
Have an integer count of the number of active work items, mutex protected. In addition, have two condition variables, one for signalling the worker threads that work is available on a queue, the other to signal the main thread that a thread has finished. Something like:
main:
set freethreads to numthreads
init mutex M, condvars TOMAIN and TOWORKER
start N worker threads
while true:
wait for work item
claim M
while freethreads == 0:
cond-wait TOMAIN, M
put work item in queue
decrement freethreads
cond-signal TOWORKER
release M
worker:
init
while true:
claim M
while no work in queue:
cond-wait TOWORKER, M
get work to local storage
release M
do work
claim M
increment freethreads
cond-signal TOMAIN
release M
Note that the loops run forever. In reality, there would be signals which made them exit and run termination/cleanup code.
Have you thought about using a counting semaphore?
From the point of view of architecturing, it'd be the responsibility of the thread pool. Synchronization between the workers and the pool should be exists.
pthread_mutex_lock() or counting semaphore (sem_wait() and sem_post() ) is good for such synchronization. One way to do that can be illustrated as:
- the pool init's the counting semaphore by calling: sem_init(p_to_sem_t, 0, int n);
- n workers acquire the semaphore by calling: sem_wait();
- the pool waits for the workers to come back by calling: sem_wait();
- the pool checks the semaphore count to see if all workers are parked.
- worker(s) release their lock when they're exiting by calling: sem_post();
精彩评论