1つのスレッドで実行する必要があり、多くのスレッドでフィードできる関数のワークキューを作成しようとしています。これを実現するために、boost::packaged_taskとboost::unique_futureを使用することを計画していました。アイデアはあなたがするだろう:
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::anyを使用する以外に選択肢はないと思います。
std::list<boost::any> queue; // note: I'm not concerned with thread-safety yet
しかし、executeSingleを実装しようとすると問題が発生します(実行するためにキューから1つのアイテムだけを取り出します)。
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の戻りタイプは気にせず、実行したいだけですが、テンプレートの詳細は理解できます。
どんな洞察も大歓迎です!