之前和大家介绍过QNX上的线程同步方法metux和semophore,通过这两种方法可以对一个或者几个资源进行加锁,避免资源使用上的冲突。在另一种情况下,某个线程需要在其它线程完成工作后才继续执行,这时就需要使用到线程同步方法barrier。

举个现实的例子,假设有三个士兵在操作一门高炮,一个负责装填炮弹,一个负责调整高炮左右方向,一个负责调整高炮角度。很明显高炮需要在三名士兵完成任务后才能发射,否则要么打不准,要么炮弹根本打不出去。

一种解决方法是给高炮设置三个按钮,只有三个按钮都按下了高炮才发射,这样不管哪个士兵完成任务了,他只需要按下自己负责的按钮,一旦三个按钮都按下,说明三个士兵的工作都完成了,就发射炮弹。

这个有三个按钮的装置就可以说是一个屏障,保证高炮可以正常工作。

下面就以这个例子做一个barrier测试。

首先需要引入头文件,包括:

#include <stdlib.h>

#include <stdio.h>

#include <pthread.h>

#include <sync.h>

#include <sched.h>

#include <unistd.h>

其中pthread.h和sync.h是关键,一个用于线程创建,一个用于barrier。

然后定义一个pthread_barrier_t全局变量:

pthread_barrier_t barrier;

 

接着在main函数里初始化barrier:

pthread_barrier_init(&barrier, NULL, 3);

其中第一个参数就是barrier变量,第三个参数是屏障需要等待的数量,本例就是等待3个士兵完成任务,所以设置成3.

然后启动三个士兵的线程,每个士兵线程负责完成一件工作,完成之前有一个delay的循环,表示完成工作需要的时间,不同士兵线程delay的时间不同,表示完成不同工作需要不同的时间。

所有士兵线程完成工作后都调用pthread_barrier_wait方法,通知barrier工作以完成,并开始等待,调用方法如下,唯一的参数就是初始化好的barrier变量:

pthread_barrier_wait(&barrier);

一旦   pthread_barrier_wait执行完成,表示所用工作都完成了,就发射炮弹,通过打印“Fire!”表示。

printf("SoldierX:::::::::: Fire! \n");

另外,主线程启动三个士兵线程后进入一个循环等待,同时输出一些时间信息。

程序执行结果如下:

Entering Barrier Test

creating the barrier

creating the threads

Soldier1:::::::::: Adjusting angle

Soldier2:::::::::: Adjusting direction

Soldier3:::::::::: Filling bullet

timer in main thread:0

timer in main thread:1

timer in main thread:2

timer in main thread:3

timer in main thread:4

Soldier1:::::::::: angle ready!

timer in main thread:5

Soldier2:::::::::: direction ready!

timer in main thread:6

timer in main thread:7

Soldier3:::::::::: bullet ready!

Soldier3::::::::::  Fire!

Soldier1:::::::::: Fire!

Soldier2::::::::::  Fire!

timer in main thread:8

timer in main thread:9

end of main thread

可以看到,只有三个线程都完成相应任务后他们才继续往下执行,保证了大炮可以成功发射。

完整代码如下:

  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <pthread.h>
  4. #include <sync.h>
  5. #include <sched.h>
  6. #include <unistd.h>
  7. pthread_barrier_t barrier;
  8. void soldier1() {
  9. printf("Soldier1:::::::::: Adjusting angle \n");
  10. int i = 0;
  11. for (i = 0; i < 20; i++) {
  12. delay(45);
  13. }
  14. printf("Soldier1:::::::::: angle ready!\n");
  15. pthread_barrier_wait(&barrier);
  16. printf("Soldier1:::::::::: Fire! \n");
  17. }
  18. void soldier2() {
  19. printf("Soldier2:::::::::: Adjusting direction \n");
  20. int i = 0;
  21. for (i = 0; i < 20; i++) {
  22. delay(55);
  23. }
  24. printf("Soldier2:::::::::: direction ready!\n");
  25. pthread_barrier_wait(&barrier);
  26. printf("Soldier2::::::::::  Fire! \n");
  27. }
  28. void soldier3() {
  29. printf("Soldier3:::::::::: Filling bullet \n");
  30. int i = 0;
  31. for (i = 0; i < 20; i++) {
  32. delay(76);
  33. }
  34. printf("Soldier3:::::::::: bullet ready!\n");
  35. pthread_barrier_wait(&barrier);
  36. printf("Soldier3::::::::::  Fire! \n");
  37. }
  38. int main(int argc, char *argv[]) {
  39. printf("Entering Barrier Test\n");
  40. printf("creating the barrier\n");
  41. pthread_barrier_init(&barrier, NULL, 3);
  42. printf("creating the threads\n");
  43. pthread_create(NULL, NULL, &soldier1, NULL );
  44. pthread_create(NULL, NULL, &soldier2, NULL );
  45. pthread_create(NULL, NULL, &soldier3, NULL );
  46. int i = 0;
  47. for (i = 0; i < 10; i++) {
  48. printf("timer in main thread:%d\n", i);
  49. delay(200);
  50. }
  51. printf("end of main thread\n");
  52. pthread_barrier_destroy(&barrier);
  53. return EXIT_SUCCESS;
  54. }

http://blog.csdn.net/keyboardota/article/details/6867346

QNX多线程同步之Barrier(屏障)的更多相关文章

  1. linux多线程同步

    1. 互斥量是线程同步的一种机制,用来保护多线程的共享资源.同一时刻,只允许一个线程对临界区进行访问.互斥量的工作流程:创建一个互斥量,把这个互斥量的加锁调用放在临界区的开始位置,解锁调用放到临界区的 ...

  2. c#中多线程同步Lock(锁)的研究以及跨线程UI的操作

    本文只针对C#中,多线程同步所用到的锁(lock)作为研究对象.由于想更直观的显示结果,所以,在做demo的时候,就把多线程通过事件操作UI的代码也写了出来,留作备忘和分享吧. 其实多线程的同步,使用 ...

  3. C#多线程同步事件及等待句柄AutoResetEvent 和 ManualResetEvent

    最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也 ...

  4. C# 中 多线程同步退出方案 CancellationTokenSource

    C# 中提供多线程同步退出机制,详参对象: CancellationTokenSource CancellationTokenSource 中暂未提供复位操作,因此当调用Cancle 之后,若再次调用 ...

  5. Servlet基础(三) Servlet的多线程同步问题

    Servlet基础(三) Servlet的多线程同步问题 Servlet/JSP技术和ASP.PHP等相比,由于其多线程运行而具有很高的执行效率. 由于Servlet/JSP默认是以多线程模式执行的, ...

  6. Linux多线程同步方式

    当多个线程共享相同的内存时,需要确保每个线程看到一致的数据视图,当多个线程同时去修改这片内存时,就可能出现偏差,得到与预期不符合的值.为啥需要同步,一件事情逻辑上一定是有序的,即使在并发环境下:而操作 ...

  7. C# 多线程同步和线程通信

    多线程通信 1. 当线程之间有先后的依赖关系时,属于线程之间的通信问题.也就是后一个线程要等待别的一个或多个线程全部完成,才能开始下一步的工作.可以使用: WaitHandle Class WaitH ...

  8. Java多线程同步问题的探究

    一.线程的先来后到——问题的提出:为什么要有多线程同步?Java多线程同步的机制是什么? http://www.blogjava.net/zhangwei217245/archive/2010/03/ ...

  9. Java多线程同步的方法

    一 synchronized关键字 1.synchronized实现原理: ---基于对象监视器(锁) java中所有对象都自动含有单一的锁,JVM负责跟踪对象被加锁的次数.如果一个对象被解锁,其计数 ...

随机推荐

  1. P1888 三角函数

    题目描述 输入一组勾股数a,b,c(a≠b≠c),用分数格式输出其较小锐角的正弦值.(要求约分.) 输入输出格式 输入格式: 一行,包含三个数,即勾股数a,b,c(无大小顺序). 输出格式: 一行,包 ...

  2. deploy sql clr

    1, create strong signed key file 2, create asymmetric key

  3. css3之BFC、IFC、GFC和FFC

    CSS2.1中只有BFC和IFC, CSS3中才有GFC和FFC. What's FC?一定不是KFC,FC的全称是:Formatting Contexts,是W3C CSS2.1规范中的一个概念.它 ...

  4. CF1041F Ray in the tube构造_思维

    不难发现起点必定是一个点. 每次间隔的距离一定是 2k2^k2k,关键就是要判断两点是否在同一跳跃距离上可被同时覆盖. 我们可以对上边进行 x1≡x_{1}\equivx1​≡ x2mod(2∗dx) ...

  5. P3376 【模板】网络最大流(luogu)

    P3376 [模板]网络最大流(luogu) 最大流的dinic算法模板(采取了多种优化) 优化 时间 inline+当前弧+炸点+多路增广 174ms no 当前弧 175ms no 炸点 249 ...

  6. 查看系统进程:ps、top

    1.ps命令:提供最近进程的快照.显示当前活跃进程的简要信息. 常见使用: (1)与grep命令配合查找是否有相应进程存活 ps -ef | grep ksmd ps -Af | grep ksmd ...

  7. mycql 基本mysql语句(增删改查)

    操作文件夹(库) 增 (增加一个库 db1 ) create database db1 charset utf8; 查 # 查看当前创建的数据库 show create database db1; # ...

  8. Manacher(最大回文字串)

    很好的讲解 注意两端的字符要不同,同时数组要开大一些 [Manacher]最长回文子串 #include<bits/stdc++.h> #define REP(i, a, b) for(r ...

  9. VS2015 C# 编写USB通信上位机时,改变net框架导致DLL调用失败的问题解决方法

    最近在写USB通信的上位机,调用了windows里的DLL,开发环境:64位WIN7 .VS2015.NET4.5.2:开发完成后在自己的电脑可用,在32位电脑.NET其他版本以及WIN10的环境下不 ...

  10. STM32 抢占优先级和响应优先级

    一.抢占优先级和响应优先级 STM32 的中断向量具有两个属性,一个为抢占属性,另一个为响应属性,其属性编号 越小,表明它的优先级别越高. 抢占,是指打断其他中断的属性,即因为具有这个属性会出现嵌套中 ...