Barriers 使用场景
类似的线程并行执行,比如算从1加到100,分成五个线程,每个线程算20个数的加法。Barriers可以使先算完的线程等待后面的线程。
后面会用一段代码写这个例子。
数据结构
pthread_barrier_t
pthread_barrierattr_t
关键操作
int pthread_barrier_init(pthread_barrier_t *restrict barrier,const pthread_barrierattr_t *restrict attr, unsigned int count);
和其它的锁初始化相比,它多一个参数,这个count,的意思就是我们要同步的线程个数,比如之前的举的例子5个线程共同计算,那么count就等于5
int pthread_barrier_destroy(pthread_barrier_t *barrier);
int pthread_barrier_wait(pthread_barrier_t *barrier);
这个函数有三种返回值,0表示成功,PTHREAD_BARRIER_SERIAL_THREAD不但返回成功,最后的总结任务也落到这个线程上。否则返回错误码!
高级操作
int pthread_barrierattr_init(pthread_barrierattr_t * attr);
int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict attr, int *restrict pshared);
int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr,int pshared);
测试例子:
1.
#include<pthread.h>#include<stdio.h>pthread_cond_t cond = PTHREAD_COND_INITIALIZER;pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_barrier_t barrier;static int flag = 0;void *test1 (void *arg){ int i = 0; while (1) { pthread_mutex_lock (&mutex); while (flag != 1) pthread_cond_wait (&cond, &mutex); printf (“T1\n”); flag = 2; pthread_mutex_unlock (&mutex); pthread_cond_broadcast (&cond); i++; if (i > 3) break; } pthread_barrier_wait (&barrier);}void *test2 (void *arg){ int i = 0; while (1) { pthread_mutex_lock (&mutex); while (flag != 2) pthread_cond_wait (&cond, &mutex); printf (“T2\n”); flag = 3; pthread_mutex_unlock (&mutex); pthread_cond_broadcast (&cond); i++; if (i > 3) break; } pthread_barrier_wait (&barrier);}void *test3 (void *arg){ int i = 0; while (1) { pthread_mutex_lock (&mutex); while (flag != 3) pthread_cond_wait (&cond, &mutex); printf (“T3\n”); flag = 1; pthread_mutex_unlock (&mutex); pthread_cond_broadcast (&cond); i++; if (i > 3) break; } pthread_barrier_wait (&barrier);}intmain (){ pthread_t p1, p2, p3; pthread_barrier_init (&barrier, NULL, 4); pthread_create (&p1, NULL, test1, 0); pthread_create (&p2, NULL, test2, 0); pthread_create (&p3, NULL, test3, 0); pthread_mutex_lock (&mutex); flag = 1; pthread_mutex_unlock (&mutex); pthread_cond_signal (&cond); pthread_barrier_wait (&barrier); pthread_barrier_destroy (&barrier); printf (“END\n”); return 0;}
2.
#include<pthread.h>#include<stdio.h>pthread_barrier_t barrier;void *calcu (void *arg){ int *p = arg; int sum = 0; int i; for (i = 0; i < 20; i++) { sum += p[i]; } *(int*)arg = sum; pthread_barrier_wait (&barrier);}intmain (){ pthread_t p1, p2, p3, p4, p5; int array[100]; int i, ret = 0; for (i = 1; i <= 100; i++) array[i – 1] = i; pthread_barrier_init (&barrier, NULL, 6); pthread_create (&p1, NULL, calcu, &array[0]); pthread_create (&p2, NULL, calcu, &array[20]); pthread_create (&p3, NULL, calcu, &array[40]); pthread_create (&p4, NULL, calcu, &array[60]); pthread_create (&p5, NULL, calcu, &array[80]); pthread_barrier_wait (&barrier); for (i = 0; i < 5; i++) ret += array[i * 20]; printf (“%d\n”, ret); return 0;}