基本概念:
屏障(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环境高级编程》·第三版
本文永久更新地址://m.ajphoenix.com/linux/23368.html