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


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

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

    程序执行结果如下:

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

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

  • 相关阅读:
    POJ 2411 Mondriaan's Dream
    POJ 2505 A multiplication game
    HDOJ(HDU) 3949 XOR
    雅礼集训DAY 6 T1 xmasdag
    bzoj 2159: Crash 的文明世界
    如何查看Ubuntu版本
    Ubuntu如何安装谷歌Chrome浏览器
    使用nano编辑器进行查找和替换
    Ubuntu修改用户和root密码
    Anaconda/Conda创建环境时报错的解决方案
  • 原文地址:https://www.cnblogs.com/feng9exe/p/8343333.html
Copyright © 2020-2023  润新知