Linux编程- pthread_barrier_xxx介绍

      By:Ailson Jack

      Date:2016.04.03

      个人博客:www.only2fire.com

      本文在我博客的地址是:http://www.only2fire.com/archives/59.html,排版更好,便于学习。

      pthread_barrier_xxx系列函数在<pthread.h>中定义,用于多线程的同步,它包含下列三个函数:

      —pthread_barrier_init();

      —pthread_barrier_wait();

      —pthread_barrier_destroy();

      那么pthread_barrier_xxx是用来做什么的?这三个函数又怎么配合使用呢?

      pthread_barrier_xxx其实只做且只能做一件事,就是充当栏杆(barrier意为栏杆)形象的说就是把先后到达的多个线程挡在同一栏杆前,直到所有线程到齐,然后撤下栏杆同时放行。

      1)、init函数负责指定要等待的线程个数;

      2)、wait()函数由每个线程主动调用,它告诉栏杆“我到起跑线前了”。wait()执行末尾栏杆会检查是否所有人都到栏杆前了,如果是,栏杆就消失所有线程继续执行下一句代码;如果不是,则所有已到wait()的线程停在该函数不动,剩下没执行到wait()的线程继续执行;

      3)、destroy函数释放init申请的资源。

1、函数原型

#include <pthread.h>

int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count);

int pthread_barrier_wait(pthread_barrier_t *barrier);

int pthread_barrier_destroy(pthread_barrier_t *barrier);

      参数解释:

pthread_barrier_t:是一个计数锁,对该锁的操作都包含在三个函数内部,我们不用关心也无法直接操作,只需要实例化一个对象丢给它就好。

pthread_barrierattr_t:锁的属性设置,设为NULL让函数使用默认属性即可。

count:你要指定的等待个数。

2、使用场景

      这种“栏杆”机制最大的特点就是最后一个执行wait的动作最为重要,就像赛跑时的起跑枪一样,它来之前所有人都必须等着。所以实际使用中,pthread_barrier_xxx常常用来让所有线程等待“起跑枪”响起后再一起行动。比如我们可以用pthread_create()生成100个线程,每个子线程在被create出的瞬间就会自顾自的立刻进入回调函数运行。但我们可能不希望它们这样做,因为这时主进程还没准备好,和它们一起配合的其它线程还没准备好,我们希望它们在回调函数中申请完线程空间、初始化后停下来,一起等待主进程释放一个“开始”信号,然后所有线程再开始执行业务逻辑代码。

      为了解决上述场景问题,我们可以在init时指定n+1个等待,其中n是线程数。而在每个线程执行函数的首部调用wait()。这样100个pthread_create()结束后所有线程都停下来等待最后一个wait()函数被调用。这个wait()由主进程在它觉得合适的时候调用就好。最后这个wait()就是鸣响的起跑枪。

3、程序示例

       下面的程序,在main函数中,pthread_barrier_init()指定2+1个等待,接着创建了2个线程,然后主进程延时6秒,之后调用pthread_barrier_wait()来让线程接着运行,程序如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

/*
********************************************************************************
*描述:pthread_barrier_xxx程序示例
*Use:gcc pthread_barrier_xxx.c -lpthread
*    ./a.out
*By:Ailson Jack
*Date:2016.03.24
*Blog:www.only2fire.com
********************************************************************************
*/


#include        <stdio.h>
#include        <unistd.h>
#include        <pthread.h>
#include        <time.h>

pthread_barrier_t barrier;

void *Task1(void *arg);
void *Task2(void *arg);

int main(void)
{
    int policy,inher;
    pthread_t tid;
    pthread_attr_t attr;
    struct sched_param param;

    //初始化线程属性
    pthread_attr_init(&attr);
    pthread_barrier_init(&barrier,NULL,2 + 1);//2+1个等待

    //创建线程1
    pthread_create(&tid, &attr,Task1,NULL);

    //创建线程2
    pthread_create(&tid, &attr,Task2,NULL);
    
    printf("main process will sleep 6s.\r\n");
    sleep(6);/*等待6s后,才让线程运行*/
    pthread_barrier_wait(&barrier);//起跑枪“砰!”

    pthread_join(tid, NULL);
    pthread_barrier_destroy(&barrier);
}

void *Task1(void *arg)
{
    printf("Task1 will be blocked.\r\n");
    pthread_barrier_wait(&barrier);//所有线程都被阻塞在这里
    printf("Task1 is running.\r\n");
    sleep(3);//延时3s
    pthread_exit(NULL);
}

void *Task2(void *arg)
{
    printf("Task2 will be blocked.\r\n");
    pthread_barrier_wait(&barrier);//所有线程都被阻塞在这里
    printf("Task2 is running.\r\n");
    sleep(3);//延时3s
    pthread_exit(NULL);
}

      程序的运行结果如下图所示:

2016-03-24_142825

      注:转载请注明出处,谢谢!^_^

  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jackailson

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值