线程总结3-屏障
线程总结3-屏障
0. 屏障
屏障是用户协调多个线程并行工作的同步机制。屏障允许所有的合作线程都到达某一点,然后从该点继续执行。
1. 相关函数
1.1. 初始化
#include<pthread.h>
int pthread_barrier_init(pthread_barrier_t *restrict barrier,
const pthread_barrierattr_t *restrict attr,
unisgned int count);
int pthread_barrier_destory(pthread_barrier_t *barrier);
count 参数设置允许所有线程继续执行之前吗,必须达到屏障的线程数目。
1.2. wait函数
int pthread_barrier_wait(pthread_barrier_t *barrier);
调用pthread_barrier_wait
函数的线程在屏障计数没有达到count时,会进入休眠状态。如果该线程是最后一个调用pthread_barrier_wait
的线程,就满足了屏障计数,所有线程都会被唤醒。
对于一个任意线程,pthread_barrier_wait
函数返回了PTHREAD_BARRIER_SERIAL_THREAD
。剩下的线程看到的返回值都是0。这使得一个线程可以作为主线程,它可以工作在其他所有线程已完成的工作结果上。
2. 例程
例程1: 老师给10个学生各自分配一个task,task难易程度不同,因此耗时也不尽相同。每个学生完成自己的task后,输出"task[i] accomplished in m minutes!"
。等到所有同学都完成了各自任务,老师宣布"mission accomplished!"
。
#include<pthread.h>
#define NTHR 10
void* task(void *arg);
pthread_barrier_t barrier;
int main()
{
int err, i;
pthread_t tid;
pthread_barrier_init(&barrier, NULL, NTHR + 1);
for (i = 0; i < NTHR; i++) {
err = pthread_create(&tid, NULL, task, (void*)(i));
if (err != 0) {
printf("create thread error!\n");
return -1;
}
}
pthread_barrier_wait(&barrier);
printf("mission accomplished!\n");
return 0;
}
void* task(void *arg)
{
int i, t;
i = (int)arg;
t = rand() % 10 + 1;
// 睡几秒钟,假装我们在执行任务
sleep(t);
printf("task %d accomplished in %d minutes\n", i, t);
pthread_barrier_wait(&barrier);
return ((void*)0);
}
完整例程参见barrier-ex01.c
例程2: 对1000万个随机数进行排序。
在这个例子中,我们创建了100个线程,每个线程对10万个数字进行堆排序,排序完成后,在主线程进行合并。
int main()
{
int err, i;
pthread_t tid;
printf("INT_MAX = %d\n", INT_MAX);
srand(time(NULL));
for (i = 0; i < NUMNUM; i++) {
// sleep_ms(1);
nums[i] = rand() % INT_MAX;
}
// 初始化barrier
pthread_barrier_init(&barrier, NULL, NTHR + 1);
// 创建100个排序线程
for (i = 0; i < NTHR; i++) {
err = pthread_create(&tid, NULL, sort, (void*)(i * TNUM));
if (err != 0) {
printf("create thread error!\n");
return -1;
}
}
pthread_barrier_wait(&barrier);
//合并排序结果
merge();
printf("-------------------------------------\n");
for (i = 0; i < NUMNUM; i++) {
// nums[i] = random();
printf("%10d \n", nums[i]);
if ((i + 1) % TNUM == 0) {
printf("-------------------------------------\n");
}
}
return 0;
}
完整例程参见barrier-ex02.c
3.参考资料
[1.] 《unix环境高级编程》第11章