zoukankan      html  css  js  c++  java
  • pthread_barrier_init,pthread_barrier_wait简介(转)

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

         --pthread_barrier_init()
    
          --pthread_barrier_wait()
    
          --pthread_barrier_destroy()

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

    pthread_barrier_*其实只做且只能做一件事,就是充当栏杆(barrier意为栏杆)。形象的说就是把先后到达的多个线程挡在同一栏杆前,直到所有线程到齐,然后撤下栏杆同时放行。1)init函数负责指定要等待的线程个数;2) wait()函数由每个线程主动调用,它告诉栏杆“我到起跑线前了”。wait()执行末尾栏杆会检查是否所有人都到栏杆前了,如果是,栏杆就消失所有线程继续执行下一句代码;如果不是,则所有已到wait()的线程停在该函数不动,剩下没执行到wait()的线程继续执行;3)destroy函数释放init申请的资源。

    1 使用场景举例:

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

    解决方案:

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

    2 函数原型:

    1 #include <pthread.h>
    2 
    3 int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_t *restrict attr, unsigned count);
    4 
    5 int pthread_barrier_wait(pthread_barrier_t *barrier);
    6 
    7 int pthread_barrier_destroy(pthread_barrier_t *barrier);

    参数解释:

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

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

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

    3 程序举例:

     1 #include <pthread.h>
     2 
     3 class thisclass{
     4 
     5 private:
     6 
     7          static void* doSomething(void* arg)
     8 
     9          {
    10 
    11                    thisclass* pInstance = (thisclass*) arg;
    12 
    13                    pthread_barrier_wait(pInstance->barrier);//所有线程都被阻塞在这里
    14 
    15                    //下面是线程具体要做的事
    16 
    17                    //...
    18 
    19          }
    20 
    21          
    22 
    23 protected:
    24 
    25          pthread_barrier_t barrier;
    26 
    27          int thread_num; // = 100;
    28 
    29          pthread_t* thread;
    30 
    31  
    32 
    33 public:
    34 
    35          int init(){ //生成100个等待的线程
    36 
    37                    int ret = -1;
    38 
    39                    pthread_attr_t attr;
    40 
    41                    pthread_attr_init(&attr);
    42 
    43                    do{
    44 
    45                             if(thread_num == 0 
    46 
    47                                  || (thread = (pthread_t*)malloc(thread_num *sizeof(pthread_t))) == NULL)
    48 
    49                                      break;
    50 
    51                             pthread_barrier_init(&barrier,NULL, thread_num + 1); //100+1个等待
    52 
    53                             for(i=0; i<thread_num; i++)
    54 
    55                                      if(pthread_create(thread+i, &attr, doSomething, this)) 
    56 
    57                                                break; //100个create成功的线程都进入上面的doSomething函数执行
    58 
    59                             if(i!= thread_num) 
    60 
    61                                      break;
    62 
    63                             ret= 0;
    64 
    65                    }while(false)
    66 
    67                    return ret;
    68 
    69          }
    70 
    71          int activate(){ //等一切都安排好了调用该函数。起跑枪“砰!”
    72 
    73                    pthread_barrier_wait(barrier);
    74 
    75                    return0;
    76 
    77          }
    78 
    79 }

    4 三个函数的英文说明见这里,里面有更细节的语法介绍:

    http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_barrier_wait.html

    http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_barrier_init.html

    转自:苏冉旭博客,http://hi.baidu.com/new/hehehehello

  • 相关阅读:
    sql优化
    一些有用的单词(1)
    用到的 Sed 注解
    终端工具注册码
    nginx四层、七层负载均衡配置示例
    http 状态码
    04. Golang 数据类型
    03. Golang 特性
    02. Go 命令
    01. GOPATH 目录结构划分的两种风格
  • 原文地址:https://www.cnblogs.com/zl1991/p/7389834.html
Copyright © 2011-2022 走看看