为什么创建线程时出现段错误?

时间:2019-10-09 18:33:23

标签: c++ segmentation-fault stdthread

我对在这里创建和触发线程时为什么遇到分段错误感到困惑。它发生在t[j] = thread(getMax, A);行中,我很困惑为什么会发生这种情况。 threadMax[]是每个线程的最大值。 getMax()返回数组的最大值。

#include <iostream>
#include <stdlib.h>
#include <sys/time.h>
#include <thread>
#define size 10
#define numThreads 10
using namespace std;

int threadMax[numThreads] = {0};
int num =0;

void getMax(double *A){
    num += 1;
    double max = A[0];
    double min = A[0];
    for (int i =0; i<size; i++){
        if(A[i] > max){
            max = A[i];
        }
    }
    threadMax[num] = max;
}

int main(){
    int max =0;
    double S,E;
    double *A = new double[size];
    srand(time(NULL));
    thread t[numThreads];
    //Assign random values to array
    for(int i = 0; i<size; i++){
        A[i] = (double(rand()%100));
    }
    //create Threads
    for(int j =0; j <numThreads; j++){
        cout << A[j] << "    " << j << "\n";
        t[j] = thread(getMax, A);
    }

    //join threads
    for(int i =0; i< numThreads; i++){
        t[i].join();
    }

    //Find Max from all threads
    for(int i =0; i < numThreads; i++){
        if(threadMax[i] > max){
            max = threadMax[i];
        }
    }

    cout <<max;

    delete [] A;

    return 0;
}

2 个答案:

答案 0 :(得分:5)

此代码的行为未定义:

 void getMax(double *A){
        num += 1;
        double max = A[0];
        double min = A[0];
        for (int i =0; i<size; i++){
              if(A[i] > max){
                        max = A[i];
                }
        }
        threadMax[num] = max;
}

num += 1可以允许多个线程尝试同时修改num。更糟糕的是,当在num中读取threadMax[num] = max;时,线程可能会在运行时看到其他线程修改的num的值。

您需要以某种安全的方式为每个线程分配一个编号。

以下三种失败的方式:

  1. 两个线程恰好同时执行num += 1;,结果num仅递增一次。

  2. 每个线程都执行num += 1;之前,每个线程都执行threadMax[num] = max;。所有线程都会覆盖数组中的相同条目。 (实际上,这超出了范围!)

  3. 由于未定义行为,代码崩溃。

答案 1 :(得分:1)

正如其他人所述,您的num变量不受getMax()内的竞争条件的保护,这可能导致其被破坏,从而导致getMax()访问{{1 }}数组超出范围。

您可以通过完全摆脱该threadMax[]变量并将数组索引作为输入参数传递给num来避免这种情况。

尝试更多类似的方法:

std::thread