C++多线程统计素数时std::thread传参无匹配构造函数报错
编译报错原因
这个报错是因为你编译时没有指定C11及以上的语言标准,std::thread支持传入可调用对象+多个参数的构造函数是C11才新增的特性,低版本标准下没有对应构造函数,所以编译器报匹配失败。
修复步骤
第一步:修正编译指令
编译代码时添加C标准声明和线程库链接参数,以clang/g为例:g++ 你的代码文件名.cpp -o prime_count -std=c++11 -pthread
macOS下用clang编译也可以用同样参数。
第二步:修正代码逻辑错误
你当前的代码除了编译问题外还有多个逻辑错误,无法正确统计素数:
- 素数判断逻辑错误:内层循环中每次不能整除就给count加1是完全错误的,应该是内层循环遍历完所有小于i的数都没找到因数,才判定i是素数,count加1
- 计数变量作用域错误:prime函数内的count是局部变量,main函数无法访问,最后输出的count属于未声明变量,也会导致编译失败
- 线程串行执行:创建线程后立刻调用join,所有线程依次执行,完全没有发挥多线程并行的优势
- 区间拆分遗漏:如果3000000不能被输入的线程数整除,最后一段的数字会被漏算
- 素数判断效率极低:判断素数不需要遍历到i-1,只要遍历到sqrt(i)即可,计算300万的素数时效率会提升很多
修正后完整代码
#include <iostream> #include <thread> #include <vector> #include <cmath> using namespace std; // 用引用传参存每个线程的计数结果 void prime(int z, int n, int& res) { int count = 0; for (int i = z; i <= n; i++) { if (i <= 1) continue; bool is_prime = true; // 优化判断边界到sqrt(i) for (int j = 2; j <= sqrt(i); j++) { if (i % j == 0) { is_prime = false; break; } } if (is_prime) count++; } res = count; } int main() { int n, total = 3000000, y = 0; cout << "Enter the number of threads: " << endl; cin >> n; int step = total / n; vector<thread> threads; vector<int> res(n, 0); for (int i = 0; i < n; i++) { int start = y + 1; // 最后一个线程负责到末尾,避免漏数 int end = (i == n-1) ? total : step * (i+1); cout << "Thread " << i+1 << ": [" << start << ", " << end << "]\n"; // 用std::ref传递引用参数给线程 threads.emplace_back(prime, start, end, ref(res[i])); y += step; } // 所有线程创建完成后再统一join,实现并行 for (auto& t : threads) { t.join(); } // 累加所有线程的计数结果 int total_count = 0; for (int cnt : res) { total_count += cnt; } cout << "Number of primes: " << total_count << endl; return 0; }
内容的提问来源于stack exchange,提问作者Zuhriddin Musabayev
相关产品推荐
相关产品推荐

