• 【PTHREAD】线程互斥与同步之栅栏


    栅栏的功能与其字面含义大体相同,阻塞到达栅栏的线程,直到指定数目的线程全部到达。

    1 栅栏属性类型

    #define __SIZEOF_PTHREAD_BARRIERATTR_T 4
    typedef union
    {
      char __size[__SIZEOF_PTHREAD_BARRIERATTR_T];
      int __align;
    } pthread_barrierattr_t;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2 初始化与销毁栅栏属性

    int pthread_barrierattr_destroy(pthread_barrierattr_t *attr);
    int pthread_barrierattr_init(pthread_barrierattr_t *attr);
    
    • 1
    • 2

    3 栅栏属性之进程共享属性

    int pthread_barrierattr_getpshared(const pthread_barrierattr_t
                                       *restrict attr, int *restrict pshared);
    int pthread_barrierattr_setpshared(pthread_barrierattr_t *attr,int pshared);
    
    • 1
    • 2
    • 3
    • PTHREAD_PROCESS_SHARED

      能够访问栅栏内存的所有线程

    • PTHREAD_PROCESS_PRIVATE

      创建栅栏所在的进程内的所有线程

    4 栅栏结构

    # define __SIZEOF_PTHREAD_BARRIER_T 20
    typedef union
    {
      char __size[__SIZEOF_PTHREAD_BARRIER_T];
      long int __align;
    } pthread_barrier_t;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    5 初始化与销毁栅栏

    int pthread_barrier_destroy(pthread_barrier_t *barrier);
    int pthread_barrier_init(pthread_barrier_t *restrict barrier,
                             const pthread_barrierattr_t *restrict attr,
                             unsigned count);
    
    • 1
    • 2
    • 3
    • 4

    6 栅栏等待

    int pthread_barrier_wait(pthread_barrier_t *barrier);
    
    • 1

    7 案例:栅栏的使用

    • 源码

      #include 
      #include 
      #include 
      #include 
      #include 
      
      pthread_barrier_t barrier;
      
      void *start_routine_01(void *ptr)
      {
          printf("子线程(%lu)开始运行...\n", pthread_self());
          printf("子线程(%lu)栅栏等待状态前\n", pthread_self());
          pthread_barrier_wait(&barrier);
          printf("子线程(%lu)栅栏等待状态后\n", pthread_self());
          printf("子线程(%lu)即将退出...\n", pthread_self());
          return (void*)"9999";
      }
      
      void *start_routine_02(void *ptr)
      {
          printf("子线程(%lu)开始运行...\n", pthread_self());
          printf("子线程(%lu)栅栏等待状态前\n", pthread_self());
          pthread_barrier_wait(&barrier);
          printf("子线程(%lu)栅栏等待状态后\n", pthread_self());
          printf("子线程(%lu)即将退出...\n", pthread_self());
          return (void*)"9999";
      }
      
      void *start_routine_03(void *ptr)
      {
          printf("子线程(%lu)开始运行...\n", pthread_self());
          printf("子线程(%lu)栅栏等待状态前\n", pthread_self());
          pthread_barrier_wait(&barrier);
          printf("子线程(%lu)栅栏等待状态后\n", pthread_self());
          printf("子线程(%lu)即将退出...\n", pthread_self());
          return (void*)"9999";
      }
      
      int main(int argc, char const *argv[])
      {
          printf("主线程(%lu)开始运行...\n", pthread_self());
      
          pthread_barrierattr_t attr;
          pthread_barrierattr_init(&attr);
          pthread_barrier_init(&barrier, &attr, 3);
          pthread_barrier_destroy(&attr);
          
          pthread_t thread_id_01;
          pthread_create(&thread_id_01, NULL, start_routine_01, NULL);
      
          pthread_t thread_id_02;
          pthread_create(&thread_id_02, NULL, start_routine_02, NULL);
      
          pthread_t thread_id_03;
          pthread_create(&thread_id_03, NULL, start_routine_03, NULL);
      
          pthread_join(thread_id_01, NULL);
          pthread_join(thread_id_02, NULL);
          pthread_join(thread_id_03, NULL);
      
          pthread_barrier_destroy(&barrier);
          printf("主线程(%lu)即将退出...\n", pthread_self());
          exit(EXIT_SUCCESS);
      }
      
      • 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
      • 64
    • 输出

      主线程(140073106831168)开始运行…
      子线程(140073106827008)开始运行…
      子线程(140073106827008)栅栏等待状态前
      子线程(140073098434304)开始运行…
      子线程(140073098434304)栅栏等待状态前
      子线程(140073090041600)开始运行…
      子线程(140073090041600)栅栏等待状态前
      子线程(140073090041600)栅栏等待状态后
      子线程(140073090041600)即将退出…
      子线程(140073098434304)栅栏等待状态后
      子线程(140073098434304)即将退出…
      子线程(140073106827008)栅栏等待状态后
      子线程(140073106827008)即将退出…
      主线程(140073106831168)即将退出…

  • 相关阅读:
    20231010-学习笔记
    掌动智能:UI自动化测试工具产品功能和优势
    22.10.29 CF-1294C
    Go 常用标准库之 fmt 介绍与基本使用
    学python的第十八天
    在全链路追踪中加入对方法(Method)追踪
    【ROS进阶篇】第一讲 常用API介绍
    经典SQL练习题6----student/course/SC
    由《天才基本法》第三集中的一个问题引发的思考
    C++&QT-day4
  • 原文地址:https://blog.csdn.net/zhy29563/article/details/126670167