一.概述                                                   

barrier(屏障)与互斥量,读写锁,自旋锁不同,它不是用来保护临界区的。相反,它跟条件变量一样,是用来协同多线程一起工作!!!

条件变量是多线程间传递状态的改变来达到协同工作的效果。屏障是多线程各自做自己的工作,如果某一线程完成了工作,就等待在屏障那里,直到其他线程的工作都完成了,再一起做别的事。举个通俗的例子:

1.对于条件变量。在接力赛跑里,1号队员开始跑的时候,2,3,4号队员都站着不动,直到1号队员跑完一圈,把接力棒给2号队员,2号队员收到接力棒后就可以跑了,跑完再给3号队员。这里这个接力棒就相当于条件变量,条件满足后就可以由下一个队员(线程)跑。

2.对于屏障。在百米赛跑里,比赛没开始之前,每个运动员都在赛场上自由活动,有的热身,有的喝水,有的跟教练谈论。比赛快开始时,准备完毕的运动员就预备在起跑线上,如果有个运动员还没准备完(除去特殊情况),他们就一直等,直到运动员都在起跑线上,裁判喊口号后再开始跑。这里的起跑线就是屏障,做完准备工作的运动员都等在起跑线,直到其他运动员也把准备工作做完!

二.函数接口                                           

1.创建屏障

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

barrier:pthread_barrier_t结构体指针

attr:屏障属性结构体指针

count:屏障等待的线程数目,即要count个线程都到达屏障时,屏障才解除,线程就可以继续执行

2.等待

1 #include <pthread.h>
2
3 int pthread_barrier_wait(pthread_barrier_t *barrier);

函数的成功返回值有2个,第一个成功返回的线程会返回PTHREAD_BARRIER_SERIAL_THREAD,其他线程都返回0。可以用第一个成功返回的线程来做一些善后处理工作。

3.销毁屏障

1 #include <pthread.h>
2
3 int pthread_barrier_destroy(pthread_barrier_t *barrier);

三.简单例子                                           

写个简单的例子,主线程等待其他线程都完成工作后自己再向下执行,类似pthread_join()函数!

 1 /**
 2  * @file pthread_barrier.c
 3  */
 4
 5 #include <stdio.h>
 6 #include <stdlib.h>
 7 #include <string.h>
 8 #include <unistd.h>
 9 #include <pthread.h>
10
11 /* 屏障总数 */
12 #define PTHREAD_BARRIER_SIZE 4
13
14 /* 定义屏障 */
15 pthread_barrier_t barrier;
16
17 void err_exit(const char *err_msg)
18 {
19     printf("error:%s\n", err_msg);
20     exit(1);
21 }
22
23 void *thread_fun(void *arg)
24 {
25     int result;
26     char *thr_name = (char *)arg;
27
28     /* something work */
29
30     printf("线程%s工作完成...\n", thr_name);
31
32     /* 等待屏障 */
33     result = pthread_barrier_wait(&barrier);
34     if (result == PTHREAD_BARRIER_SERIAL_THREAD)
35         printf("线程%s,wait后第一个返回\n", thr_name);
36     else if (result == 0)
37         printf("线程%s,wait后返回为0\n", thr_name);
38
39     return NULL;
40 }
41
42 int main(void)
43 {
44     pthread_t tid_1, tid_2, tid_3;
45
46     /* 初始化屏障 */
47     pthread_barrier_init(&barrier, NULL, PTHREAD_BARRIER_SIZE);
48
49     if (pthread_create(&tid_1, NULL, thread_fun, "1") != 0)
50         err_exit("create thread 1");
51
52     if (pthread_create(&tid_2, NULL, thread_fun, "2") != 0)
53         err_exit("create thread 2");
54
55     if (pthread_create(&tid_3, NULL, thread_fun, "3") != 0)
56         err_exit("create thread 3");
57
58     /* 主线程等待工作完成 */
59     pthread_barrier_wait(&barrier);
60     printf("所有线程工作已完成...\n");
61
62     sleep(1);
63     return 0;
64 }

28行是线程自己要做的工作,62行的sleep(1)让所有线程有足够的时间把自己的返回值打印出来。编译运行:

可以看到,3个线程工作完成后才可以越过屏障打印返回值,第一个返回的是PTHREAD_BARRIER_SERIAL_THREAD,其他都是0。

这里有一点要注意:我们从运行结果看出,主线程打印"所有线程工作已完成"之后,线程1,线程2还在运行打印返回值。这个结果难免会误解"主线程等待所有线程完成工作之后再向下执行"。区分一点即可:等待只针对屏障之前的动作,越过屏障后,无论是主线程,还是子线程都会并发执行,如果非要让子线程完完全全执行完,可以再加个屏障到线程函数末尾,相应主线程也要加!

linux线程同步(5)-屏障相关推荐

  1. linux:线程同步的5种方法

    linux:线程同步的5种方法 一.为什么要使用线程: 二.线程同步的5种方法 2.1 互斥量 2.2 读写锁 2.3 条件变量 2.4 自旋锁 2.5 屏障 一.为什么要使用线程: <1> ...

  2. Linux线程同步(二)---互斥锁实现线程同步

    一 why 先给自己打个广告,本人的微信公众号:嵌入式Linux江湖,主要关注嵌入式软件开发,股票基金定投,足球等等,希望大家多多关注,有问题可以直接留言给我,一定尽心尽力回答大家的问题. 在博客&l ...

  3. linux线程同步的方法

    #Linux 线程同步的三种方法 线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. ##一.互斥锁 ...

  4. Linux 线程同步的三种方法

    程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的同 ...

  5. linux 线程流水线,linux线程同步

    我是linux和linux线程的新手.我花了一些时间谷歌搜索试图理解可用于线程同步的所有函数之间的差异.我还有一些问题. 我找到了所有这些不同类型的同步,每个同步都有许多锁定,解锁,测试锁等功能. g ...

  6. 信号灯文件锁linux线程,linux——线程同步(互斥量、条件变量、信号灯、文件锁)...

    一.说明 linux的线程同步涉及: 1.互斥量 2.条件变量 3.信号灯 4.文件读写锁 信号灯很多时候被称为信号量,但个人仍觉得叫做信号灯比较好,因为可以与"SYSTEM V IPC的信 ...

  7. Linux线程的同步,linux线程同步

    我是linux和linux线程的新手.我花了一些时间谷歌搜索试图理解可用于线程同步的所有函数之间的差异.我还有一些问题. 我找到了所有这些不同类型的同步,每个同步都有许多锁定,解锁,测试锁等功能. & ...

  8. linux线程同步互斥说法,linux线程间的同步与互斥知识点总结

    在线程并发执行的时候,我们需要保证临界资源的安全访问,防止线程争抢资源,造成数据二义性. 线程同步: 条件变量 为什么使用条件变量? 对临界资源的时序可控性,条件满足会通知其他等待操作临界资源的线程, ...

  9. Linux线程同步与Windows线程同步

    简介 线程同步概念:在多线程下,在一段时间内只允许一个线程访问资源,不允许其它线程访问. 在WIN32中,同步机制主要有以下几种: (1)事件(Event); (2)信号量(semaphore); ( ...

最新文章

  1. HDU2255(最全权完美匹配)
  2. leetcode算法题--单词拆分★
  3. MongoDB Windows环境安装及配置
  4. 软件设计原则——接口隔离原则
  5. 2021湖北高考个人成绩排名查询,2021湖北高考总成绩一分一段排名
  6. 递归和分治思想及其应用
  7. linux jetty 安装目录结构,Linux下Jetty 9安装部署
  8. 看完这篇后,别再说你不懂JVM类加载机制了~
  9. 小白初学MySQL----Win7下关于安装和初步使用~
  10. pythonpandas无列名数据合并_python – Pandas:合并多个数据帧和控制列名?
  11. python mooc-课程资源 | Python语言系列专题MOOC
  12. web网页设计实例作业 ——丝绸之路 (6页) 简单个人网页设计作业 静态HTML文化主题网页
  13. 4399ATAPI讲解操作事件篇
  14. 从零开始系统化学Android,手慢无
  15. 第十三届蓝桥杯省赛C++B组题解
  16. Word中插入手写体签名
  17. 微信小程序云开发初步上手
  18. android sdl,能通吃所有安卓手机的SDL究竟是何神通?
  19. Linux 两台主机之间建立信任关系方式及基本原理
  20. 自学编程?别傻了!一张图让你认清自己和科班程序员的差别!

热门文章

  1. mysql常用表名大全_MySQL常用命令大全
  2. 可变车道怎么走不违章_郑州街头现可变车道?该咋走?记者实地探访
  3. 面试题整理13 合并排序链表去重
  4. 【自动驾驶】31.【相机外参标定】、【相机障碍物后处理】【地面的2D点反投影到3D】的过程对比
  5. android适配器Adapter
  6. Java 中 ConcurrentHashMap 原理分析
  7. 语言堆栈入门——堆和栈的区别
  8. Spring MVC 入门示例讲解
  9. Java 8的6个问题
  10. OpenCV学习笔记(十六)——CamShift研究 OpenCV学习笔记(十七)——运动分析和物体跟踪Video OpenCV学习笔记(十八)——图像的各种变换(cvtColor*+)imgproc