我想構建一個需要由一個線程執行的函數的工作隊列,並且可以由很多線程提供。爲了做到這一點,我打算使用boost :: packaged_task和boost :: unique_future。這個想法是你會這樣做的:如何使用返回任意類型的函數來創建一個持有boost :: packaged_task <>的隊列?
Foo value = queue.add(myFunc).get();
這會阻塞,直到函數被執行。所以queue.add(...)接受一個boost :: function,並返回一個boost :: unique_future。然後在內部使用boost :: function爲其構造函數創建boost :: packaged_task。
我遇到的問題是boost :: function < ...>每次都不一樣。具體來說,它的返回值將會改變(但函數永遠不會採用任何參數)。因此,我必須有一個附加功能,看起來像:
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 ::任何,因爲該類型將不是恆定:
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 ::任何,但我得到的錯誤:
conversion from 'boost::any' to non-scalar type boost::detail::thread_move_t<boost:thread>' requested.
有趣的是,我其實並不關心在這一點packaged_task的返回類型,我只是想執行它,但我可以弄清楚模板的細節。
任何有識之士將不勝感激!
這個錯誤源於這樣一個事實,即當你真的應該使用'boost :: any_cast'時,你試圖從'any'中構造一個'packaged_task'。但請參閱下面的答案。 – 2011-05-05 04:15:50