我对在这里创建和触发线程时为什么遇到分段错误感到困惑。它发生在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;
}
答案 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
的值。
您需要以某种安全的方式为每个线程分配一个编号。
以下三种失败的方式:
两个线程恰好同时执行num += 1;
,结果num
仅递增一次。
每个线程都执行num += 1;
之前,每个线程都执行threadMax[num] = max;
。所有线程都会覆盖数组中的相同条目。 (实际上,这超出了范围!)
由于未定义行为,代码崩溃。
答案 1 :(得分:1)
正如其他人所述,您的num
变量不受getMax()
内的竞争条件的保护,这可能导致其被破坏,从而导致getMax()
访问{{1 }}数组超出范围。
您可以通过完全摆脱该threadMax[]
变量并将数组索引作为输入参数传递给num
来避免这种情况。
尝试更多类似的方法:
std::thread