是否存在pthread_join()的resultval返回0而不是线程返回值的情况?

问题描述 投票:0回答:1

我正在尝试创建一个多线程程序,该程序将在与可执行文件相同的目录中逐行搜索多个文件,以查找短语“ Hello World”的子字符串。每个文件都由单独的线程处理。

[不幸的是,第一个线程返回的0代表读取的模式数量,而不是正确的值,而所有其他后续线程返回的都是正确值。在内部,即使对于第一个返回错误值的线程,该线程也会显示正确数量的模式。我只是不明白为什么它返回错误的值。我是否误解了pthread_join()的工作方式?

FILE1.txt: 1. hello world Red
FILE1.txt: 2. hello world world
Total patterns found in FILE1.txt: 2
FILE2.txt: hello world 1
FILE2.txt: hello world 2
FILE2.txt: hello world 3
Total patterns found in FILE2.txt: 3
[MAIN] Thread 1 returned with the value of: 0 <---- incorrect value. It should instead read as 2.
[MAIN] Thread 2 returned with the value of: 3
[MAIN] Total of 3 patterns found out of 10 lines scanned
#include <iostream>
#include <cstring>
#include <pthread.h>
#include <stdio.h>

#define MAXBUFF 50

void *searchfile(void *arg);

int totalScans = 0;
char *pattern;
pthread_mutex_t lock;


using namespace std;


int main(int argc, char *argv[]) {
    int err,
        sumPatterns = 0;
    int mainPatterns[argc-2];
    pthread_t tID[argc-2];
    void *(results);
    if(argc < 3) { 
        cout << "Enter at least three arguments.\n";
        return 1;
    }
    string str(argv[1]);
    pattern = &str[0];
    for(int i = 0; i < (argc-2); i++) {
        err = pthread_create(&tID[i], NULL, searchfile, (void *)argv[i+2]);
        if(err != 0) {
            cout << "Thread " << i << " could not be created\n";
            return 1;
        }
        pthread_join(tID[i], &results);
        mainPatterns[i] = *((int *)results);
    }
    for(int i = 0; i < (argc-2); i++) { 
        cout << "[MAIN] Thread " << i+1 << " returned with the value of: " << mainPatterns[i] << endl;
        sumPatterns += mainPatterns[i];
    }
    cout << "[MAIN] Total of " << sumPatterns << " patterns found out of " << totalScans << " lines scanned\n";
    pthread_mutex_destroy(&lock);
    return 0;
}


void *searchfile(void *arg) {
    pthread_mutex_lock(&lock);
    int *threadPatterns;
    int a = 0;
    threadPatterns = &a;
    char readLine[MAXBUFF];
    char *carg = (char *)arg;
    char *strP;
    FILE *stream = fopen(carg, "r");
    if(!stream) {
        cout << "Could not open file stream. Error: " << strerror(errno) << "\n";
        pthread_mutex_unlock(&lock);
        return 0;
    }
    while(fgets(readLine, MAXBUFF, stream) != NULL) {
        strP = strstr(readLine, pattern);
        if(strP) {
            cout << carg << ": " << readLine;
            a++;
        }
        totalScans++;
    }
    if(fclose(stream) == -1) {
        cout << "Could not close file stream. Error: " << strerror(errno) << "\n";
        pthread_mutex_unlock(&lock);
        exit(2);
    }
    cout << "Total patterns found in " << carg << ": " << *threadPatterns << "\n"; 
    pthread_mutex_unlock(&lock);
    return (void *)threadPatterns;
}
c++ linux multithreading pthreads
1个回答
1
投票
int *threadPatterns;
int a = 0;
threadPatterns = &a;

...

return (void *)threadPatterns;

&a是局部变量的地址,该局部变量在searchfile()返回时被破坏。线程结束后,该地址不再有效,对其进行访问将调用未定义的行为。

要修复它,请返回线程结束后将存在的地址。这可能是全局变量或静态变量,或者可能是从主线程传入的指针,也可能是使用malloc()分配的堆内存。如果您执行了最后一个操作,则完成后,主线程应将其free()

int *threadPatterns = malloc(sizeof(int));

if (!threadPatterns) {
    // handle allocation failure
}

...

return threadPatterns;

0
投票

您可以查看pthread_exit()以从线程返回任何值。但是,如果要从pthread.join()返回一些值,则可以使用全局变量。Man Page for pthread_join

Understanding pthread_exit

© www.soinside.com 2019 - 2024. All rights reserved.