三种方式实现Barrier

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;
}
posted @ 2022-11-08 19:45  jakekiller00  阅读(66)  评论(0编辑  收藏  举报