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

时间:2012-10-21 23:02:14

标签: c++ multithreading pointers pthreads segmentation-fault

这是我的代码,它使用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 Thread\n";
            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";

}

我没有从我的threadFunction正确调用return吗?我一直在尝试一些不同的东西,我仍然不知道发生了什么......任何帮助将不胜感激! (我打开的文本文件每行包含一个X或Y.我的目标是计算20个文本文件中X和Y的总数)

3 个答案:

答案 0 :(得分:0)

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

应该是

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

您要求联接将returnedItem的值设置为您的线程函数返回的任何void* ...因此您需要提供{{>地址 {{ 1}}。

答案 1 :(得分:0)

pthread_join()的第二个参数是void**,其结果将存储在其中。但是,您传递的是随机值。这可能应该是这样的:

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

当然,这假设确实返回了data*

答案 2 :(得分:0)

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);