首页 > 其他分享 >三种方式实现Barrier

三种方式实现Barrier

时间:2022-11-08 19:57:41浏览次数:32  
标签:Barrier 方式 int Thread mutex pthread print 三种 include

1.利用pthread_t对计数器进行加锁,线程没有全到达之前进行忙等待;

#include<iostream>
#include<pthread.h>
#define num 8
using namespace std;
typedef struct thread_item{
    int thread_id;
}Thread_PARAM;
pthread_mutex_t mutexs;
pthread_mutex_t print;
pthread_cond_t cond;
int counter=0;
void * func(void * args) {
    Thread_PARAM *p = (Thread_PARAM *) args;

    pthread_mutex_lock(&print);
    cout<<"step1:  id=" <<p->thread_id<<endl;
    pthread_mutex_unlock(&print);
    pthread_mutex_lock(&mutexs);
    counter++;
    pthread_mutex_unlock(&mutexs);
    while (counter < num);
    pthread_mutex_lock(&print);
    cout<<"step2:  id=" <<p->thread_id<<endl;
    pthread_mutex_unlock(&print);
    pthread_exit(NULL);
}
int main(){
    pthread_mutex_init(&mutexs, NULL);
    pthread_mutex_init(&print, NULL);
    pthread_cond_init(&cond, NULL);
    pthread_t thread[num];
    Thread_PARAM thread_param[num];
    for(int i=0;i<num;i++){
        thread_param[i].thread_id = i;
        pthread_create(&thread[i],NULL,func,(void*)&thread_param[i]);
    }
    for(int j=0;j<num;j++){
        pthread_join(thread[j],NULL);
    }
    return 0;
}

2.利用pthread_cond_wait和pthread_cond_broadcast进行阻塞和唤醒;

注:

#include<iostream>
#include<pthread.h>
#define num 8
using namespace std;
typedef struct thread_item{
    int thread_id;
}Thread_PARAM;
pthread_mutex_t mutexs;
pthread_mutex_t print;
pthread_cond_t cond;
int counter=0;
void * func(void * args){
    Thread_PARAM *p=(Thread_PARAM*)args;

    pthread_mutex_lock(&print);
    cout<<"step1:  "<<"id:"<<p->thread_id<<endl;
    pthread_mutex_unlock(&print);
    pthread_mutex_lock(&mutexs);
    counter++;
    while(counter!=num){
        pthread_cond_wait(&cond,&mutexs);
    }
    pthread_cond_broadcast(&cond);
    pthread_mutex_unlock(&mutexs);

    pthread_mutex_lock(&print);
    cout<<"step2:   "<<"id: "<<p->thread_id<<endl;
    pthread_mutex_unlock(&print);
}
int main(){
    pthread_mutex_init(&mutexs, NULL);
    pthread_mutex_init(&print, NULL);
    pthread_cond_init(&cond, NULL);
    pthread_t thread[num];
    Thread_PARAM thread_param[num];
    for(int i=0;i<num;i++){
        thread_param[i].thread_id = i;
        pthread_create(&thread[i],NULL,func,(void*)&thread_param[i]);
    }
    for(int j=0;j<num;j++){
        pthread_join(thread[j],NULL);
    }
    return 0;
}

3.利用sem_t信号量机制实现;

#include<semaphore.h>
#include<iostream>
#include<pthread.h>
#define num 8
using namespace std;
pthread_mutex_t print;
typedef struct {
    int threadId;
} threadParm_t;
int counter = 0; //判断有多少线程抵达了路障
sem_t count_sem; //用于保护计数器
sem_t barrier_sem; //用于阻塞已经进入路障的线程。

void *threadFunc(void *parm) {
    threadParm_t *p = (threadParm_t *) parm;

    pthread_mutex_lock(&print);
    cout<<"step1: id="<<p->threadId<<endl;
    pthread_mutex_unlock(&print);

    //一进来一个线程,就阻塞一下,这样子是达到一定数量之后把门关上,和Barrier完全相反的作用;
    sem_wait(&count_sem);
    if(counter==num-1){
        counter=0;
        sem_post(&count_sem);
        for(int i=0;i<num-1;i++) {
            sem_post(&barrier_sem);
        }
    }
    else{
        counter++;                // 计数器加一
        sem_post(&count_sem);   // 解锁计数器
        sem_wait(&barrier_sem); // 等待栅栏解锁
    }


    pthread_mutex_lock(&print);
    cout<<"step2: id="<<p->threadId<<endl;
    pthread_mutex_unlock(&print);

    pthread_exit(NULL);
}

int main() {
    pthread_mutex_init(&print, NULL);
    sem_init(&barrier_sem, 0, 0);
    sem_init(&count_sem, 0, 1);
    pthread_t thread[num];
    threadParm_t threadParm[num];
    int i;
    for (i = 0; i < num; i++) {
        threadParm[i].threadId = i;
        pthread_create(&thread[i], NULL, threadFunc, (void*) &threadParm[i]);
    }
    for (i = 0; i < num; i++) {
        pthread_join(thread[i], NULL);
    }
    sem_destroy(&count_sem);
    sem_destroy(&barrier_sem);
    return 0;
}

标签:Barrier,方式,int,Thread,mutex,pthread,print,三种,include
From: https://www.cnblogs.com/NKshen/p/barrier.html

相关文章

  • 面向对象的魔法方法、魔法方法笔试题、元类简介、创建类的两种方式、元类定制类的产生
    面向对象的魔法方法魔法方法:类中定义的双下方法都称为魔法方法 不需要人为调用在特定的条件下回自动触发运行 eg:__init__创建空对象之后自动触发给对象添加独有的数......
  • Java的三种代码注释
    Java的三种代码注释单行注释://文字多行注释:/*文字*/JavaDoc(文档注释):/***/如:/****/......
  • 三种方式部署若依前后端分离环境
    一、环境准备:1.下载源码并解压:​​https://gitee.com/y_project/RuoYi-Vue​​2.前端工程配置修改及打包:进入ruoyi-ui项目下的vue.config.js文件里的服务端口和后端地址:在ru......
  • CyclicBarrier适用场景
    1、CyclicBarrier无法阻塞主线程,不适合在需要同步返回的接口中使用。CountDownLatch可以阻塞主线程,适用于需要同步返回的接口2、CyclicBarrier适用于异步任务,尤其需要对子......
  • 5种从JavaScript 数组中删除项目的方式
    英文| https://javascript.plainenglish.io/how-to-remove-an-item-from-a-javascript-array-in-5-ways-2932b2686442翻译|杨小二有很多方法可以从JavaScript数组中删......
  • unity3D. 移动的几种方式和区别
    Transform 放在Update中transform.Translate();----------------------------------------------------------------------------Rigidbody.物理放在FixedUpdate中......
  • 中科三方IPv6改造方案技术答疑:IPv6转换的两种技术方式
    与双栈技术和隧道技术相比,IPv6转换技术具备改造周期短、成本低、部署灵活等优势,是目前各大政企网站进行IPv6升级改造的主要方式。采用协议转换实现IPv4到IPv6过渡的优点是......
  • 【转载】Python格式化4种方式
    Python格式化字符串的4种方式一:%号    %号格式化字符串的方式从Python诞生之初就已经存在时至今日,python官方也并未弃用%号,但也并不推荐这种格式化方式。 #1、格......
  • React性能优化的8种方式
    一引沿Fiber架构是React16中引入的新概念,目的就是解决大型React应用卡顿,React在遍历更新每一个节点的时候都不是用的真实DOM,都是采用虚拟DOM,所以可以理解成fiber就是R......
  • 12种JS常用获取时间的方式
    在编程中,总会遇到各种各样的获取时间的要求,下面我们来看一下获取不同时间格式的方法有哪些?如果不记得的话建议收藏哦!1、获取当前的日期和时间方法:newDate()​console.log(n......