我正在尝试创建一个多线程程序,该程序将在与可执行文件相同的目录中逐行搜索多个文件,以查找短语“ 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;
}
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;
您可以查看pthread_exit()以从线程返回任何值。但是,如果要从pthread.join()返回一些值,则可以使用全局变量。Man Page for pthread_join