使用pthread调用自定义函数报类型转换编译错误如何解决?
问题原因及解决方案
核心问题原因
- pthread_create要求传入的线程入口函数必须符合固定签名:
void* (*)(void*),即返回值为void*类型,且仅接收1个void*类型的入参。你当前编写的findword函数签名为void findword(char *str, string word),返回值、参数数量、参数类型均不符合要求,因此编译报类型转换错误。 - 除此之外你的代码还存在3个隐藏问题:
- 原
findword函数的for循环边界写为i <= a.size(),会触发vector下标越界访问,vector合法下标范围为0 ~ a.size()-1 - 字符串分割函数
strtok是线程不安全函数,多线程环境下调用会出现不可预期的异常 - 你传入pthread的自定义结构体参数,原
findword函数没有对应的解析逻辑,参数无法正常传递
- 原
修复方案
第一步:调整线程入口函数,使其符合pthread签名要求,同时修复隐藏bug
struct findwordargs { char *str; string word; }; // 新的线程入口函数,符合pthread签名要求 void* thread_findword(void* args) { // 把void类型的参数转回自定义结构体类型 findwordargs* real_args = static_cast<findwordargs*>(args); char *str = real_args->str; string word = real_args->word; char *p; vector<string> a; // 替换为线程安全的分割函数strtok_r char* saveptr; p = strtok_r(str, " ", &saveptr); while (p != NULL) { a.push_back(p); p = strtok_r(NULL, " ", &saveptr); } int c = 0; // 修正越界问题,把<=改为< for (int i = 0; i < a.size(); i++) if (word == a[i]) c++; printf("%d", c); // 线程函数必须返回void*,无返回需求时返回NULL即可 return NULL; }
第二步:修改pthread_create调用,传入新的入口函数
struct findwordargs firstwordArguments; firstwordArguments.str = copy; firstwordArguments.word = "polar"; pthread_t thread_id; // 第三个参数替换为调整后的线程入口函数 pthread_create(&thread_id, NULL, thread_findword, static_cast<void*>(&firstwordArguments)); pthread_join(thread_id, NULL);
额外优化建议
如果使用C++11及以上版本,可以直接用std::thread实现多线程,无需手动处理参数类型转换,写法更简洁:
// 直接调用你原来的findword函数即可 std::thread t(findword, copy, "polar"); t.join();
内容的提问来源于stack exchange,提问作者kikikey
相关产品推荐
相关产品推荐

