红联Linux门户
Linux帮助

linux多线程之屏障

发布时间:2016-08-16 15:28:41来源:linux网站作者:带鱼兄
基本概念:
屏障(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;  
}  
 
运行结果:
linux多线程之屏障
 
参考:《unix环境高级编程》·第三版
 
本文永久更新地址://m.ajphoenix.com/linux/23368.html