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 

       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 

       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 
#include 
#include 
#include 
#include 
#include 

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多线程之屏障_第1张图片


参考:《unix环境高级编程》·第三版

End;

你可能感兴趣的:(linux之线程操作)