我有一个模式匹配程序,它将一个字符串作为输入并返回一个与字典非常匹配的字符串。由于该算法需要几秒钟来运行一个匹配查询,所以我尝试使用多线程来运行批处理查询。
我首先读入一个包含查询列表的文件,并为每个查询调度一个新线程来执行匹配算法,使用 pthread_join 将结果返回到一个数组中。
但是,我得到了一些不一致的结果。例如,如果我的查询文件包含术语“红、绿、蓝”,我可能会收到“红、绿、绿”作为结果。另一次运行可能会产生正确的“红、绿、蓝”结果。它似乎有时会覆盖数组中的结果,但是为什么会发生这种情况,因为数组值是根据线程 id 设置的?
Dictionary dict; // global, which performs the matching algorithm
void *match_worker(void *arg) {
char* temp = (char *)arg;
string strTemp(temp);
string result = dict.match(strTemp);
return (void *)(result.c_str());
}
void run(const string& queryFilename) {
// read in query file
vector<string> queries;
ifstream inquery(queryFilename.c_str());
string line;
while (getline(inquery, line)) {
queries.push_back(line);
}
inquery.close();
pthread_t threads[queries.size()];
void *results[queries.size()];
int rc;
size_t i;
for (i = 0; i < queries.size(); i++) {
rc = pthread_create(&threads[i], NULL, match_worker, (void *)(queries[i].c_str()));
if (rc) {
cout << "Failed pthread_create" << endl;
exit(1);
}
}
for (i = 0; i < queries.size(); i++) {
rc = pthread_join(threads[i], &results[i]);
if (rc) {
cout << "Failed pthread_join" << endl;
exit(1);
}
}
for (i = 0; i < queries.size(); i++) {
cout << (char *)results[i] << endl;
}
}
int main(int argc, char* argv[]) {
string queryFilename = arg[1];
dict.init();
run(queryFilename);
return 0;
}
编辑:正如 Zac 所建议的,我修改了线程以明确地将结果放在堆上:
void *match_worker(void *arg) {
char* temp = (char *)arg;
string strTemp(temp);
int numResults = 1;
cout << "perform match for " << strTemp << endl;
string result = dict.match(strTemp, numResults);
string* tmpResult = new string(result);
return (void *)((*tmpResult).c_str());
}
虽然,在这种情况下,我会将删除调用放在哪里?如果我尝试将以下内容放在 run() 函数的末尾,它会给出一个无效的指针错误。
for (i = 0; i < queries.size(); i++) {
delete (char*)results[i];
}