Linux编程- pthread_barrier_xxx介绍
2016-04-03 22:53
465 查看
By:Ailson Jack
Date:2016.04.03
个人博客:www.only2fire.com
本文在我博客的地址是:http://www.only2fire.com/archives/848.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()来让线程接着运行,程序如下:
程序的运行结果如下图所示:
注:转载请注明出处,谢谢!^_^
Date:2016.04.03
个人博客:www.only2fire.com
本文在我博客的地址是:http://www.only2fire.com/archives/848.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); } |
注:转载请注明出处,谢谢!^_^
相关文章推荐
- Linux技术——gdb调试基础
- 第六周分析Linux内核创建一个新进程的过程
- LinuxC高级编程——线程间同步
- Linux内核设计第六周 ——进程的描述和创建
- linux如何设置无密码登录mysql(如何设置无密码登陆mysql)
- Linux内核分析——进程的描述和创建
- linux下core文件调试方法
- 在centos6 或 RHEL 6上使用yum测试zabbix 2.4
- LINUX内核分析第六周学习总结:进程的描述和进程的创建
- CentOS 7.1编译安装PHP7
- linux高编线程-------线程的取消
- Linux混杂设备驱动模型
- Linux下安装JDK
- Linux SSH 远程登录错误解决办法 WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
- QEMU虚拟机安装linux操作系统
- linux调整/etc/sysctl.conf
- Linux之压缩与解压缩
- linux compile objective-c
- lab6:分析Linux内核创建一个新进程的过程
- 《Linux内核设计与实现》读书笔记 3