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 函数原型:

#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,你要指定的等待个数。

3 程序举例:

#include <pthread.h>

class thisclass{

private:

static void* doSomething(void* arg)

{

thisclass* pInstance = (thisclass*) arg;

pthread_barrier_wait(pInstance->barrier);//所有线程都被阻塞在这里

//下面是线程具体要做的事

//...

}

protected:

pthread_barrier_t barrier;

int thread_num; // = 100;

pthread_t* thread;

public:

int init(){ //生成100个等待的线程

int ret = -1;

pthread_attr_t attr;

pthread_attr_init(&attr);

do{

if(thread_num == 0

|| (thread = (pthread_t*)malloc(thread_num *sizeof(pthread_t))) == NULL)

break;

pthread_barrier_init(&barrier,NULL, thread_num + 1); //100+1个等待

for(i=0; i<thread_num; i++)

if(pthread_create(thread+i, &attr, doSomething, this))

break; //100个create成功的线程都进入上面的doSomething函数执行

if(i!= thread_num)

break;

ret= 0;

}while(false)

return ret;

}

int activate(){ //等一切都安排好了调用该函数。起跑枪“砰!”

pthread_barrier_wait(barrier);

return0;

}

}

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

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

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

pthread_barrier_init,pthread_barrier_wait简介的更多相关文章

  1. pthread_barrier_init,pthread_barrier_wait简介(转)

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

  2. ASP.NET Core 1.1 简介

    ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...

  3. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  4. Cassandra简介

    在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...

  5. REST简介

    一说到REST,我想大家的第一反应就是“啊,就是那种前后台通信方式.”但是在要求详细讲述它所提出的各个约束,以及如何开始搭建REST服务时,却很少有人能够清晰地说出它到底是什么,需要遵守什么样的准则. ...

  6. Microservice架构模式简介

    在2014年,Sam Newman,Martin Fowler在ThoughtWorks的一位同事,出版了一本新书<Building Microservices>.该书描述了如何按照Mic ...

  7. const,static,extern 简介

    const,static,extern 简介 一.const与宏的区别: const简介:之前常用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量. 执行时刻:宏是预编 ...

  8. HTTPS简介

    一.简单总结 1.HTTPS概念总结 HTTPS 就是对HTTP进行了TLS或SSL加密. 应用层的HTTP协议通过传输层的TCP协议来传输,HTTPS 在 HTTP和 TCP中间加了一层TLS/SS ...

  9. 【Machine Learning】机器学习及其基础概念简介

    机器学习及其基础概念简介 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现的深入理解.本系列文章是作者结 ...

随机推荐

  1. UART,USART,SPI,I2C等总线的介绍与区别20160526

    首先来说一下UART和USART的区别: 1.字面意义: UART:universal asynchronous receiver and transmitter通用异步收发器: USART:univ ...

  2. IEnumerable 接口 实现foreach 遍历 实例

    额 为啥写着东西? 有次面试去,因为用到的时候特别少 所以没记住, 这个单词 怎么写! 经典的面试题: 能用foreach遍历访问的对象的要求? 答:  该类实现IEnumetable 接口   声明 ...

  3. Android Service学习之本地服务

    Service是在一段不定的时间运行在后台,不和用户交互应用组件.每个Service必须在manifest中 通过来声明.可以通过contect.startservice和contect.bindse ...

  4. 在C#使用文件监控对象FileSystemWatcher的几种方案

    最近在项目中有这么个需求,就是得去实时获取某个在无规律改变的文本文件中的内容.首先想到的是用程序定期去访问这个文件,因为对实时性要求很高,间隔不能超过1S,而且每次获取到文本内容都要去分发给web服务 ...

  5. python pandas/numpy

    import pandas as pdpd.merge(dataframe1,dataframe2,on='common_field',how='outer') replace NaN datafra ...

  6. FPGA中如何实现除法?

    摘自:<xilinx FPGA 开发实用教程> 1)被除数重复的减去除数,直到检测到余数小于除数为止,优点:对于除数与被除数相差较小的情况下合适 2)通过如下图片方式实现+状态机.优点:挺 ...

  7. VIM实用基本操作技巧

    文本编辑器有很多,图形模式下有gedit.kwrite等编辑器,文本模式下的编辑器有vi.vim(vi的增强版本)和nano.vi和vim是Linux系统中最常用的编辑器.有人曾这样的说过在世界上有三 ...

  8. 在数据表中添加一个字段的SQL语句怎么写

    如果要在数据表中添加一个字段,应该如何表示呢?下面就为您介绍表添加字段的SQL语句的写法,希望可以让您对SQL语句有更深的认识.   通用式: alter table [表名] add [字段名] 字 ...

  9. 软件工程随堂小作业——寻找“水桶”(C++)

    一.设计思想 思路与寻找一个水王相似,这次只是计数器和嫌疑人变量都设置为数组.每次选取一个ID与三个嫌疑人比较,若有相同则计数:若三个都不相同,则三个计数器都减一.若减为0,则从新赋值给嫌疑人. 二. ...

  10. ubuntu 下root用户无法访问声音设备的解决方案

    原因:root用户没有对pulsaudio的访问权限,而且pulsaudio默认是不能在root下自动启动解决办法: 一.修改自动启动:编辑 gedit /etc/default/pulseaudio ...