You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pthread配合屏障实现共享数组读写出现非预期行为问题求助

问题排查与修复方案

核心问题1:线程参数传递错误

你在创建线程的循环里定义的struct args args_是栈上临时变量,循环每执行一次迭代,这个变量的内存就会被释放/覆盖,你把它的地址传给刚创建的子线程,子线程后续访问这个地址时拿到的全是非法值,自然会出现参数错乱、访问到无效内存的问题,这是导致输出异常的核心原因。

核心问题2:屏障逻辑适配验证

你当前设置的屏障计数为51,每个子线程要执行2次pthread_barrier_wait(对应每个子线程处理2行数据的循环),主线程也执行2次pthread_barrier_wait,这个次数是匹配的,本身逻辑没有问题,只要参数传递正确屏障就能正常生效。


修复代码要点

  • 将线程参数改为堆分配,或者提前分配数组存储所有线程的参数,避免临时变量被销毁导致野指针
  • 修复后不需要添加任何休眠函数即可得到预期结果

修复后的完整代码

#include <iostream>
#include <unistd.h>
#include <pthread.h>

struct args {
    double* array;
    int start;
    int stop;
    double myVal;
    double* row;
    pthread_barrier_t* barrier;
};

void* mythread(void* arguments){
    struct args* args_ = (struct args*)arguments;
    double* array = args_->array;
    int start = args_->start;
    int stop = args_->stop;
    double myVal = args_->myVal;
    pthread_barrier_t* barrier = args_->barrier;
    double* row = args_->row;

    for(int i = start; i < stop; i++){
        pthread_barrier_wait(barrier);
        for(int j = 0; j < 10; j++){
            double a = row[j];
            int ind = i*10 + j;
            array[ind] = a + myVal;
        }
    }
    delete args_;
    return NULL;
}


int main(){
    pthread_t threads[50];
    int start_ = 0;
    double* array_0 = new double[100*10]();
    double* row = new double[10]();
    pthread_barrier_t barrier;
    pthread_barrier_init(&barrier, NULL, 50+1);

    for(int n = 0; n < 50; n++){
        // 堆分配独立参数内存,避免野指针
        struct args *args_ = new struct args;
        args_->start = start_;
        args_->stop = start_ + 2;
        start_ = start_ + 2;
        args_->array = array_0;
        args_->myVal = n;
        args_->row = row;
        args_->barrier = &barrier;
        pthread_create(&threads[n], NULL, mythread, (void*)args_);
    }

    for(int i = 0; i < 2; i++){
        for(int k = 0; k < 10; k++){
            row[k] = i+1;
        }
        pthread_barrier_wait(&barrier);
    }

    for(int n = 0; n < 50; n++){
        pthread_join(threads[n], NULL);
    }
    
    // 输出结果
    for(int i = 0; i < 100; i++){
        for(int j = 0; j < 10; j++){
            int ind = i*10 + j;
            std::cout << " " << array_0[ind];
        }
        std::cout << std::endl;
    }

    // 内存清理
    delete[] array_0;
    delete[] row;
    pthread_barrier_destroy(&barrier);
    return 0;
}

效果说明

修复后运行会完全符合预期:每两行数值连续相同,前50行数值为1 + 行序号/2,后50行数值为2 + 行序号/2,不会再出现随机0值或乱码。

内容的提问来源于stack exchange,提问作者alvrm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 03:27:02