基本概念:
屏障(barrier)是用户协调多个线程并行工作的同步机制。屏障允许每个线程等待,直到所有的合作线程都达到某一点,然后从该点继续执行。
一、初始化与销毁
PTHREAD_BARRIER_DESTROY(P) POSIX Programmer's ManualPTHREAD_BARRIER_DESTROY(P) NAME pthread_barrier_destroy, pthread_barrier_init - destroy and initialize a barrier object (ADVANCED REALTIME THREADS) SYNOPSIS #include <pthread.h> int pthread_barrier_destroy(pthread_barrier_t *barrier); int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count); 两个函数的返回值:若成功,返回0;否则,返回错误编号 初始化屏障时,可以使用count参数指定,在允许所有线程继续运行之前,必须到达屏障的线程数目。屏障属性attr设置为NULL表示使用默认属性。
二、等待其他线程
PTHREAD_BARRIER_WAIT(P) POSIX Programmer's Manual PTHREAD_BARRIER_WAIT(P) NAME pthread_barrier_wait - synchronize at a barrier (ADVANCED REALTIME THREADS) SYNOPSIS #include <pthread.h> int pthread_barrier_wait(pthread_barrier_t *barrier); 返回值:若成功,返回0或者PTHREAD_BARRIER_SERIAL_THREAD;否则,返回错误编号调用pthread_barrier_wait的线程在屏障技术count未满足条件时,会进入休眠状态。如果该线程是最后一个调用pthread_barrier_wait的线程,就满足了屏障计数,所有的线程都被唤醒。
对于一个任意线程,pthread_barrier_wait函数返回PTHREAD_BARRIER_SERIAL_THREAD。剩下的线程看到的返回值是0。这使得一个线程可以作为主线程,它可以工作在其他所有线程已完成的工作结果上。
三、屏障属性
目前定义的屏障属性只有进程共享属性。
例子,功能是简单计数,gcc pthread_barrier.c -pthread:
#include <pthread.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <sys/timeb.h> static int num1 = 0; static int num2 = 0; static int count1 = 10000000; static int count2 = 20000000; static pthread_barrier_t barrier; void Perror(const char *s) { perror(s); exit(EXIT_FAILURE); } long long getSystemTime() { struct timeb t; ftime(&t); return 1000 * t.time + t.millitm; } void* fun2(void *arg) { pthread_t thread_id = pthread_self(); printf("the thread2 id is %ld\n", (long)thread_id); int i = 1; long long t1 = getSystemTime(); for (; i<=count2; ++i) { num2 += 1; } long long t2 = getSystemTime(); printf("The thread2 num2 is %d, pay %lld ms\n", num2, (t2-t1)); pthread_barrier_wait(&barrier); } int main() { int err; pthread_t thread1; pthread_t thread2; const int thread_num = 2; thread1 = pthread_self(); printf("the thread1 id is %ld\n", (long)thread1); //init pthread_barrier_init(&barrier, NULL, thread_num); // Create thread err = pthread_create(&thread2, NULL, fun2, NULL); if (err != 0) { Perror("can't create thread2\n"); } err = pthread_detach(thread2); if (err != 0) { Perror("can't detach thread2\n"); } int i = 1; long long t1 = getSystemTime(); for (; i<=count1; ++i) { num1 += 1; } long long t2 = getSystemTime(); printf("The thread1 num1 is %d, pay %lld ms\n", num1, (t2-t1)); pthread_barrier_wait(&barrier); long long t3 = getSystemTime(); printf("the thread1 get SERIAL, num1+num2=%d, pay %lld ms\n", num1+num2, t3-t1); pthread_barrier_destroy(&barrier); return 0; }运行结果:
参考:《unix环境高级编程》·第三版
End;