我写了下面的代码,它给出了一个错误;
ipt.cpp:在函数'bool isprimet(long unsigned int,int)'中: ipt.cpp:28:86:错误:无法调用'(std :: thread)(void(&)(long unsigned int,long unsigned int,long unsigned int,bool),const long unsigned int&amp ;, long unsigned int&,long unsigned int&,unsigned int&)' for(unsigned long c = 0; c
我做错了什么?
#include <iostream>
#include <thread>
#include <math.h>
using namespace std;
void ipt(const unsigned long number, const unsigned long root, const unsigned long threadid, bool &result)
{
result=true;
for (unsigned long c=5+threadid*6;c<=root;c+=(threadid+1)*6)
{
if(number % c-1 == 0) {result=false; break;};
if(number % c+1 == 0) {result=false; break;};
}
}
bool isprimet(const unsigned long number, const int nthreads)
{
if (number > 1)
{
if (number > 3)
{
if (number % 2 == 0) return false;
if (number % 3 == 0) return false;
unsigned int results[nthreads];
unsigned long root=(unsigned long)floor(sqrt(number))+1;
thread t[nthreads];
for (unsigned long c=0;c<nthreads;c++) t[c](ipt, number, root, c, results[c]);
for (unsigned long c=0;c<nthreads;c++) t[c].join();
for (unsigned long c=0;c<nthreads;c++) if (results[c]==false) return false;
return true;
}
else return true;
}
else return false;
}
答案 0 :(得分:1)
使用std::thread
时,需要将可调用对象发送到std::thread
的构造函数,并且可以使用Lambda表达式:
t[c] = new thread([&](){ ipt(number, root, c, results[c]); });
以下代码有效:
#include <thread>
#include <math.h>
#include <iostream>
using namespace std;
static int const MAX_THREADS = 128;
void ipt(const unsigned long number, const unsigned long root, const unsigned long threadid, bool &result)
{
result = true;
for (unsigned long c = 5 + threadid * 6; c <= root; c += (threadid + 1) * 6)
{
if (number % c - 1 == 0) { result = false; break; };
if (number % c + 1 == 0) { result = false; break; };
}
}
bool isprimet(const unsigned long number, const unsigned long nthreads)
{
if (number > 1)
{
if (number > 3)
{
if (number % 2 == 0) return false;
if (number % 3 == 0) return false;
bool results[MAX_THREADS];
unsigned long root = (unsigned long)floor(sqrt(number)) + 1;
thread* t[MAX_THREADS];
for (unsigned long c = 0; c < nthreads; c++)
t[c] = new thread([&](){ ipt(number, root, c, results[c]); });
for (unsigned long c = 0; c < nthreads; c++) {
t[c]->join();
delete t[c];
}
for (unsigned long c = 0; c < nthreads; c++)
if (results[c] == false)
return false;
return true;
}
else return true;
}
else return false;
}
int main(int argc, char *argv[])
{
for (int i = 1; i < 100; ++i)
if (isprimet(i,5))
cout << i << "\n";
return 0;
}
答案 1 :(得分:1)
您的代码存在两个问题,它们都出现在此行中:
for (unsigned long c=0;c<nthreads;c++) t[c](ipt, number, root, c, results[c]);
应该是这样的:
for (unsigned long c=0;c<nthreads;c++) t[c] = std::thread(ipt, number, root, c, std::ref(results[c]));
第一个问题是你调用函数的方式 - 你可以使用我在上面显示的赋值运算符。
其次,参数传递给线程的默认方式是按值。但是,您的函数原型指定您希望通过引用传递results[c]
,因此您需要使用std::ref(results[c])
明确说明。
此外,您使用非const变量设置静态数组的大小(因此编译器在编译时不知道大小),因此所有编译器警告。您需要使用常量来设置大小,或者定义一个全局常量并使用它,或者将线程数作为模板参数传递,这将消除编译器警告。
这是一个live demo到一个没有警告的工作示例。