zoukankan      html  css  js  c++  java
  • barrier内存屏障

    pthread使用barrier栅栏方式同步

    Linux中提供了多种同步机制,其中使用barrier(栅栏)是多线程之间进行同步的方法之一。

    基本原理

    假设多个线程约定一个栅栏,只有当所有的线程都达到这个栅栏时,栅栏才会放行,否则到达此处的线程将被阻塞

    使用场景

    程序启动的时候,需要建立一个独立的线程去做一些特殊的工作。比如这个线程需要初始化一些全局配置等等。而主线程启动后,必须等待这个子线程拿到配置信息后,才能继续工作。所以这里就存在一个问题要解决,主线程如何等待这个子线程完成工作后,才继续往下执行呢?

    栅栏相关API

    #include <pthread.h>
    //初始化栅栏,栅栏需要等待到count个线程,才会全部一起放行。
    int   pthread_barrier_init(pthread_barrier_t *restrict,
                            const pthread_barrierattr_t *restrict, unsigned count);
    //报道函数,当一个线程到达栅栏的时候,就报道。
    //所有的线程都报道后,栅栏自然会放行。
    int   pthread_barrier_wait(pthread_barrier_t *barrier);
    栅栏完成历史使命后,当然是功成身退。
    int pthread_barrier_destroy(pthread_barrier_t *barrier);

    使用示例

    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    #include <string.h>
    #include <pthread.h>
    #include <unistd.h>
    pthread_barrier_t barrier;
    void* initor(void* args) {
        printf("---------------thread init work(%d)--------------
    ", time(NULL));
        //模拟初始化工作。
        sleep(10);
        //到达栅栏
        pthread_barrier_wait(&barrier);
        printf("--------------thread start work(%d)--------------
    ", time(NULL));
        sleep(10);
        printf("--------------thread stop work(%d)--------------
    ", time(NULL));
        return NULL;
    }
    int main(int argc, char* argv[]) {
          //初始化栅栏,该栅栏等待两个线程到达时放行
        pthread_barrier_init(&barrier, NULL, 2);
        printf("**************main thread barrier init done****************
    ");
        pthread_t pid;
        pthread_create(&pid, NULL, &initor, NULL);
        printf("**************main waiting(%d)********************
    ", time(NULL));
        //主线程到达,被阻塞,当初始化线程到达栅栏时才放行。
        pthread_barrier_wait(&barrier);
        pthread_barrier_destroy(&barrier);
        printf("***************main start to work(%d)****************
    ", time(NULL));
        sleep(30);
        pthread_join(pid, NULL);
        printf("***************thread complete(%d)***************
    ", time(NULL));
        return 0;
    }
    root@ubuntu:/data1# gcc test.c -lpthread  -o test
    root@ubuntu:/data1# ./test
    **************main thread barrier init done****************
    **************main waiting(1615809746)********************
    ---------------thread init work(1615809746)--------------
    --------------thread start work(1615809756)--------------
    ***************main start to work(1615809756)****************
    --------------thread stop work(1615809766)--------------
    ***************thread complete(1615809786)***************
    root@ubuntu:/data1# 
    #include <stdio.h>
    #include <pthread.h>
    
    #define THREAD_NUMS 4
    pthread_barrier_t barrier;
    
    void *t0(void *param)
    {
        pthread_barrier_wait(&barrier);
        printf("t0 ready
    ");
    }
    void *t1(void *param)
    {
        pthread_barrier_wait(&barrier);
        printf("t1 ready
    ");
    }
    void *t2(void *param)
    {
        pthread_barrier_wait(&barrier);
        printf("t2 ready
    ");
    }
    
    int main(void)
    {
        pthread_t t[3];
    
        pthread_barrier_init(&barrier, NULL, THREAD_NUMS);
    #include <stdio.h>
    #include <pthread.h>
    
    #define THREAD_NUMS 4
    pthread_barrier_t barrier;
    
    void *t0(void *param)
    {
        pthread_barrier_wait(&barrier);
        printf("t0 ready
    ");
    }
    void *t1(void *param)
    {
        pthread_barrier_wait(&barrier);
        printf("t1 ready
    ");
    }
    void *t2(void *param)
    {
        pthread_barrier_wait(&barrier);
        printf("t2 ready
    ");
    }
    
    int main(void)
    {
        pthread_t t[3];
    
        pthread_barrier_init(&barrier, NULL, THREAD_NUMS);
    
        pthread_create(&t[0], NULL, t0, NULL);
        pthread_create(&t[1], NULL, t1, NULL);
        pthread_create(&t[2], NULL, t2, NULL);
    
        pthread_barrier_wait(&barrier);
        printf("all sub threads ready, go!
    ");
    
        pthread_barrier_destroy(&barrier);
    
    }
        pthread_create(&t[0], NULL, t0, NULL);
        pthread_create(&t[1], NULL, t1, NULL);
        pthread_create(&t[2], NULL, t2, NULL);
    
        pthread_barrier_wait(&barrier);
        printf("all sub threads ready, go!
    ");
    
        pthread_barrier_destroy(&barrier);
    
    }
    root@ubuntu:/data1# gcc barrier.c -lpthread  -o barrier
    root@ubuntu:/data1# ./barrier 
    t0 ready
    t2 ready
    t1 ready
    all sub threads ready, go!
  • 相关阅读:
    防简单攻击iptables策略
    Iptables 防火墙常用配置
    9个常用iptables配置实例
    NFS服务的端口分配
    docker参数--restart=always的作用
    nginx的proxy_pass路径转发规则最后带/问题
    查看tomcat进程启动了多少个线程
    Tomcat 普通用户启动
    SSH远程执行脚本tomcat未启动
    mysql 前缀索引
  • 原文地址:https://www.cnblogs.com/dream397/p/14539603.html
Copyright © 2011-2022 走看看