【发布时间】:2016-04-19 05:31:52
【问题描述】:
我正在编写一个异步查找大量素数的程序。我通过使用TaskQueue 来实现,它本质上是一个由所有异步执行的期货组成的队列。涉及三个线程:将这些任务分配给TaskQueue 的主线程,检查期货是否有答案并决定是否存储数据的客户线程,以及启动和检查的主线程另外两个的状态。我在第 593 行收到错误:Error 2 error C2280: 'std::future<return_type>::future(const std::future<return_type> &)' : attempting to reference a deleted function e:\visualstudio\vc\include\xmemory0 593 1 MultiThreadTaskQueue 引用了文件 xmemory0,这似乎是由我 #included 的其他标头之一引用的文件。我的问题似乎是未来对象的复制构造函数的问题,可能是在复制之前被删除的对象,但我不确定在我的程序中会发生什么。这是我的代码的副本:
#include <iostream>
#include <queue>
#include <future>
#include <thread>
#include <vector>
#include <mutex>
using namespace std;
using longInt = long long unsigned int;
template <typename return_type>
class TaskQueue {
private:
queue<future<return_type>> tasks;
mutex mtx;
public:
//return a copy of the queue
queue<future<return_type>> copy() const {
return tasks;
}
//default constructor
//does nothing, waits for input
TaskQueue() {
//do nothing
}
//call constructors
//adds task to queue
template <typename ... Args, typename ... Ts>
TaskQueue(return_type(*func)(Ts...), Args&& ... args) {
tasks.push(std::async(func, args...));
}
//copy constructor
//copies another queue to this one
TaskQueue(const TaskQueue<longInt> & in) {
tasks = in.copy();
}
//setter and getter functions
//inserts a new task into the queue
template <typename ... Args, typename ... Ts>
void add(return_type(*func)(Ts...), Args&& ... args) {
tasks.push(std::async(func, args...));
}
//returns true if the task at the top of the queue is ready
bool valid() {
return tasks.front().valid();
}
//gets the value, if the value is not ready, waits for it to be ready
//pops the top task after getting it
return_type get() {
//mtx.lock();
return_type temp = tasks.front().get();
tasks.pop();
//mtx.unlock();
return temp;
}
//waits for the value of the top of the queue to become ready
void wait() {
tasks.front().wait();
}
//returns the number of tasks in the queue
int size() const {
return tasks.size();
}
};
bool HALT_ALL = false;
int MAX_TASKS_AT_ONCE = 10;
//prototypes
longInt isPrime(longInt);
void cook(TaskQueue<longInt>&);
void consumer(TaskQueue<longInt>&, vector<longInt> &);
int main() {
//declare task queue and vector to store prime numbers
TaskQueue<longInt> checkPrimes;
vector<longInt> primes;
primes.push_back(2);
int maxPrimes;
cout << "Enter max primes: ";
cin >> maxPrimes;
cout << endl;
//launch the chef thread and the customer thread
thread chef(&cook, checkPrimes);
thread customer(&consumer, checkPrimes, primes);
int previousSize = 0;
//use main to keep track of the progress of the other threads
while (primes.size() < maxPrimes) {
if (previousSize != primes.size()) {
cout << "Primes found: " << primes.size() << endl;
previousSize = primes.size();
}
else {
checkPrimes.wait();
}
}
//halt all other asynchronous operations
HALT_ALL = true;
//join other threads
chef.join();
customer.join();
//print final prime found for verification of data
cout << "Final Prime found: " << primes[primes.size() - 1] << endl;
system("PAUSE");
return 0;
}
//returns the number if it is prime or 0 if it is not
longInt isPrime(longInt n) {
if (n <= 3) {
if (n > 1) {
return n;
}
return 0;
}
if (n % 2 == 0 || n % 3 == 0) {
return 0;
}
for (unsigned short i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return 0;
}
}
return n;
}
void cook(TaskQueue<longInt>& tasks) {
longInt currentPrime = 3;
while (!HALT_ALL) {
if (tasks.size() < MAX_TASKS_AT_ONCE) {
tasks.add(isPrime, currentPrime);
currentPrime += 2;
}
}
}
void consumer(TaskQueue<longInt>& tasks, vector<longInt> & primes) {
while (!HALT_ALL) {
if (tasks.size() > 0) {
longInt temp = tasks.get();
if (temp > 0) {
primes.push_back(temp);
}
}
}
}
【问题讨论】:
标签: c++ multithreading templates asynchronous future