zl程序教程

您现在的位置是:首页 >  其他

当前栏目

QNX多线程同步之Barrier(屏障)

2023-09-11 14:18:45 时间

之前和大家介绍过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

 

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

完整代码如下: 

 

[cpp] view plain copy
  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.   
  8. pthread_barrier_t barrier;  
  9.   
  10. void soldier1() {  
  11.   
  12.     printf("Soldier1:::::::::: Adjusting angle \n");  
  13.   
  14.     int i = 0;  
  15.   
  16.     for (i = 0; i < 20; i++) {  
  17.   
  18.         delay(45);  
  19.     }  
  20.     printf("Soldier1:::::::::: angle ready!\n");  
  21.     pthread_barrier_wait(&barrier);  
  22.     printf("Soldier1:::::::::: Fire! \n");  
  23. }  
  24.   
  25. void soldier2() {  
  26.   
  27.     printf("Soldier2:::::::::: Adjusting direction \n");  
  28.   
  29.     int i = 0;  
  30.   
  31.     for (i = 0; i < 20; i++) {  
  32.   
  33.         delay(55);  
  34.     }  
  35.     printf("Soldier2:::::::::: direction ready!\n");  
  36.     pthread_barrier_wait(&barrier);  
  37.     printf("Soldier2::::::::::  Fire! \n");  
  38. }  
  39.   
  40. void soldier3() {  
  41.   
  42.     printf("Soldier3:::::::::: Filling bullet \n");  
  43.   
  44.     int i = 0;  
  45.   
  46.     for (i = 0; i < 20; i++) {  
  47.   
  48.         delay(76);  
  49.     }  
  50.     printf("Soldier3:::::::::: bullet ready!\n");  
  51.     pthread_barrier_wait(&barrier);  
  52.     printf("Soldier3::::::::::  Fire! \n");  
  53.   
  54. }  
  55.   
  56. int main(int argc, char *argv[]) {  
  57.     printf("Entering Barrier Test\n");  
  58.   
  59.     printf("creating the barrier\n");  
  60.     pthread_barrier_init(&barrier, NULL, 3);  
  61.   
  62.     printf("creating the threads\n");  
  63.     pthread_create(NULL, NULL, &soldier1, NULL );  
  64.     pthread_create(NULL, NULL, &soldier2, NULL );  
  65.     pthread_create(NULL, NULL, &soldier3, NULL );  
  66.   
  67.     int i = 0;  
  68.   
  69.     for (i = 0; i < 10; i++) {  
  70.   
  71.         printf("timer in main thread:%d\n", i);  
  72.         delay(200);  
  73.     }  
  74.   
  75.     printf("end of main thread\n");  
  76.     pthread_barrier_destroy(&barrier);  
  77.   
  78.     return EXIT_SUCCESS;  
  79. }  

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