A turnstile, also called a baffle gate, is a form of gate which allows one person to pass at a time.
When have k threads dividing into 2 phases,second must wait first finishes,can do this way:
typedef struct {
int count;
pthread_mutex_t mutex;
} Counter;
Counter *c;
int num_threads;
static void *
code (void *arg){
int i;
pthread_detach (pthread_self ());
sleep(random() % 5);
printf("%ld, 1\n", pthread_self());
pthread_mutex_lock (&c->mutex);
c->count++;
if (c->count == num_threads) //last 1 waits all the other,including itself.to post k signals,then can let all sem_wait get signals.
for (i=0;i<num_threads)
sem_post(barrier);
pthread_mutex_unlock (&c->mutex); //all need this
sem_wait(barrier);
printf("%ld, 2\n", pthread_self());
return 0;
}
2.another good way:
typedef struct {
int count;
pthread_mutex_t mutex;
} Counter;
Counter *c;
int num_threads;
static void *
code (void *arg){
pthread_detach (pthread_self ());
sleep(random() % 5);
printf("%ld, 1\n", pthread_self());
pthread_mutex_lock (&c->mutex);
c->count++;
if (c->count == num_threads)
sem_post(barrier);
pthread_mutex_unlock (&c->mutex);
sem_wait(barrier); // turnstile -|-
sem_post(barrier);// one who gets barrier will release next,i.e.only one can enter each time
printf("%ld, 2\n", pthread_self());
return 0;
}
For cyclic way
typedef struct {
int count;
pthread_mutex_t mutex;
} Counter;
Counter *c;
int num_threads;
static void *
code (void *arg){
int i, j, r;
pthread_detach (pthread_self ());
for (i=0;i<10;i++){
r = random() % 5;
sleep(r);
printf("%ld slept %d sec in phase 1\n", pthread_self(), r);
pthread_mutex_lock (&c->mutex);
c->count++;
if (c->count == num_threads)
for (j=0;j<num_threads;j++)
sem_post(barrier1);
pthread_mutex_unlock (&c->mutex);
sem_wait(barrier1);
printf("%ld phase 2\n", pthread_self());
pthread_mutex_lock (&c->mutex);//phase 2 same way with previous
c->count--;
if (c->count == 0)
for (j=0;j<num_threads;j++)
sem_post(barrier2);
pthread_mutex_unlock (&c->mutex);
sem_wait(barrier2);
}
return 0;
}