Reputation: 1299
Suppose there are NUM_TREADS
threads and they have to complete job1()
before doing job2()
. How to guarantee this to happen, like this:
void thread_func(void *arg)
{
while(1) {
job1();
some_kind_of_waiting();
job2();
}
return NULL;
}
Will a semaphore like following work or are there any other/better solutions?
{
static int done;
static sem_t semaphore;
if(__sync_fetch_and_add(&done, 1) == THREAD_NUMS-1) {
done = 0;
for(i = 0; i < THREAD_NUMS-1; i++)
sem_post(&semaphore);
} else
sem_wait(&semaphore);
}
Thanks.
Upvotes: 0
Views: 160
Reputation: 239011
This precisely the problem that pthreads barriers are intended to solve. Initialise the barrier with NUM_THREADS
(in your main function, prior to spawning the threads):
pthread_barrier_t barrier;
pthread_barrier_init(&barrier, NULL, NUM_THREADS);
and use pthread_barrier_wait()
to synchronise:
void *thread_func(void *arg)
{
while(1) {
job1();
pthread_barrier_wait(&barrier);
job2();
}
return NULL;
}
If you also need the threads to wait until all other threads have compelted job2()
before any of them can start on job1()
again, you can add a second wait on the barrier:
void *thread_func(void *arg)
{
while(1) {
job1();
pthread_barrier_wait(&barrier);
job2();
pthread_barrier_wait(&barrier);
}
return NULL;
}
Upvotes: 3
Reputation: 238311
You describe a high level concurrency control structure typically called by the name barrier. The C++ standard library has no implementation of barrier although it has been proposed and will hopefully be part of C++ standard library in the future.
Until the standard library provides a solution, you can of course implement the barrier yourself (you can use a condition variable), use a platform specific threading API or a wrapper library.
Upvotes: 1