调用 pthread_barrier_wait() 失败

Call to pthread_barrier_wait() fails

我有一个 C 语言的多线程应用程序,它对矩阵进行一些计算。我使用障碍来同步工作。我遇到了一堆奇怪的错误和不确定的行为,我意识到我忘记检查 pthread_barrier_wait() 的 return 值。

这里我声明一些全局的壁垒:

pthread_barrier_t passa,passb,check;

我有一个主要功能,它会进行一些初始化,然后生成工作人员:

double **compute (int p, double P, int n, double **a){

    int r1 = pthread_barrier_init(&passa,NULL,p);
    int r2 = pthread_barrier_init(&passb,NULL,p);
    int r3 = pthread_barrier_init(&check,NULL,p);
    if(!(r1==r2==r3==0)){printf("barrier init failed\n"); exit(1);}

    pthread_t *threads = malloc(sizeof(pthread_t)*p);
    //some admin stuff 
    //spawning threads in while loop 
    int err = pthread_create(&threads[i],NULL,&compute0,args);
        if(err){
            printf("Thread Creation Error, exiting..\n");
            exit(1);
        }
        else{ //etc

然后我有工作线程函数compute0():

void *compute0(void *argsv){
    //stuff
    while(1){
        b = pthread_barrier_wait(&check);
        if(b != PTHREAD_BARRIER_SERIAL_THREAD|| b!= 0){
            printf("b : %d\n",b);
            printf("barrier failed\n"); exit(1);
        }
        //some checks
        b = pthread_barrier_wait(&passa);
        if(b != PTHREAD_BARRIER_SERIAL_THREAD|| b!= 0){
            printf("barrier failed\n"); exit(1);
        }
        //First pass
        // work 
        b = pthread_barrier_wait(&passb);
        if(b != PTHREAD_BARRIER_SERIAL_THREAD || b!= 0){
            printf("barrier failed\n"); exit(1);
        }
        //second pass
        // more work
        }
    }
}

现在我以前从未注意到这一点,但障碍等待实际上失败了。我以前从未检查过这个的 return 值:

note: one thread is used for control, computations will be run on 2 threads
Thread Created with ID : 139740189513280
Thread Created with ID : 139740181120576
================================================================
b : -1
barrier failed
b : b : 0
make: *** [Makefile:3: all] Error 1

可能是什么原因造成的?

您有以下内容:

b != PTHREAD_BARRIER_SERIAL_THREAD || b != 0

应该是以下之一:

!( b == PTHREAD_BARRIER_SERIAL_THREAD || b == 0 )
b != PTHREAD_BARRIER_SERIAL_THREAD && b != 0

所以您可能实际上并没有收到错误。但是,让我们假设尽管出现了上述错误,但实际报告了一个错误。 This 仅将 EINVAL(表示参数错误)列为可能的错误。不过,我不会指望这是一份完整的清单。您可以使用以下内容进行验证:

errno = b;
perror("pthread_barrier_wait");
exit(1);