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);
}
int
main ()
{
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);
}
int
main ()
{
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;
}