我正在尝试构建一个需要由一个线程执行并且可以由多个线程提供的函数的工作队列。为此,我计划使用 boost::packaged_task 和 boost::unique_future。这个想法是你会这样做:
Foo 值 = queue.add(myFunc).get();
这将阻塞,直到函数被执行。所以 queue.add(...) 接受一个 boost::function,并返回一个 boost::unique_future。然后它在内部使用 boost::function 作为其构造函数创建一个 boost::packaged_task。
我遇到的问题是 boost::function<...> 每次都不一样。具体来说,它的返回值会改变(但是,函数永远不会接受任何参数)。因此,我必须有一个看起来像这样的 add 函数:
template <typename ResultType>
boost::unique_future<ResultType> add(boost::function<ResultType ()> f) {
boost::packaged_task<boost::function<ResultType ()> > task(f);
queue.push_back(task);
return task.get_future();
}
好吧,这似乎还不错,但后来我遇到了如何定义“队列”的问题。我想我别无选择,只能使用 boost::any,因为类型不会是恒定的:
std::list<boost::any> queue; // note: I'm not concerned with thread-safety yet
但是当我尝试实现我的 executeSingle 时遇到了一个问题(只从队列中取出一个项目来执行):
void executeSingle() {
boost::any value = queue.back();
boost::packaged_task<?> task = boost::packaged_task<?>(boost::move(value));
// actually execute task
task();
queue.pop_back();
}
这 '?' 表示我不确定的内容。我不能用模板调用 executeSingle,因为它是从单独的线程调用的。我尝试使用 boost::any,但出现错误:
conversion from 'boost::any' to non-scalar type boost::detail::thread_move_t<boost:thread>' requested.
有趣的是,此时我其实并不关心 packaged_task 的返回类型,我只想执行它,但我可以弄清楚模板的详细信息。
任何见解将不胜感激!