为什么我在使用 pthread_join 时会出现分段错误?

Why do I get a segmentation fault when using pthread_join?

本文关键字:分段 错误 join pthread 为什么      更新时间:2023-10-16

这是我的代码,它使用 g++ 编译和运行,但我得到了一个分段错误。我知道它发生在pthread_join声明周围,但我无法弄清楚为什么。

#include <iostream>
#include <stdio.h>
#include <fstream>
#include <pthread.h>
#include <stdlib.h>
#include <sstream>
using namespace std;
struct data{
string filename;
int x;
int y;
};
void *threadFunction(void *input){
data *file = (data *) input;
string filename = file->filename;
ifstream myFile;
int xCount = 0;
int yCount = 0;
myFile.open(filename.c_str());
string line;
while(myFile >> line){
if(line == "X"){
xCount++;
}else if(line == "Y"){
yCount++;
}
}
file->x = xCount;
file->y = yCount;
return (void *) file;
}
int main(){
pthread_t myThreads[20];
data *myData = new data[20];
for(int i = 0; i < 20; i++){
ostringstream names;
names << "/filepath/input" << i+1 << ".txt";
myData[i].filename = names.str();
myData[i].x = 0;
myData[i].y = 0;
}
for(int i = 0; i < 20; i++){
int check = pthread_create(&myThreads[i], NULL, threadFunction, (void *) &myData[i]);
if(check != 0){
cout << "Error Creating Threadn";
exit(-1);
}
}

int xCount = 0;
int yCount = 0;
for(int i = 0; i < 20; i++){
data* returnedItem;
pthread_join(myThreads[i], (void**) returnedItem);
xCount += returnedItem->x;
yCount += returnedItem->y;
}
cout << "Total X: " << xCount << "n";
cout << "Total Y: " << yCount << "n";
}

我没有从我的线程函数正确调用返回吗?我一直在尝试很多不同的事情,但我仍然不知道发生了什么......任何帮助将不胜感激!(我打开的文本文件每行包含一个 X 或 Y。我的目标是计算 20 个文本文件中 X 和 Y 的总数)

pthread_join的第二个参数将用于返回线程的值,因此pthread_join内部的某个地方我们有一个调用*secondArgument = thread_return_value的代码,但让我们看看你在这里做什么:

// You are not initializing returnedItem, so it contain some garbage value
// For example 0x12345678
data* returnedItem;
// Now you cast that garbage to (void**), and pthread_join will call
// *(0x12345678) = thread_return_value that will cause segmentation fault
pthread_join(myThreads[i], (void**) returnedItem);

但是您希望将返回值复制到returnedItem,对吗? 如果你的回答是肯定的,你应该将returnedItem的地址传递给pthread_join这样它就可以把它复制到那里。因此,请将您的呼叫更改为:

pthread_join(myThreads[i], (void**) &returnedItem);
pthread_join(myThreads[i], (void**) returnedItem);

应该是

pthread_join(myThreads[i], (void**) &returnedItem);

您要求 join 将returnedItem的值设置为线程函数返回的任何void*...所以你需要给出returnedItem的地址.

pthread_join()的第二个参数是要存储结果的void**。但是,您传递的是一个随机值。这可能看起来像这样:

void* result;
pthread_join(myThread[i], &result);
data* returnedItem = static_cast<data*>(result);

当然,这假设data*确实被归还了。