std :: futureの任意の数を作成したい場合は、それらをすべてstd :: vectorに入れるのに役立ちます。その後、ベクトルをループして結果をget
にすることができます。 get
が処理を待機していることに注意してください。
//Result type defined here: http://en.cppreference.com/w/cpp/thread/async
template<typename F, typename... Args>
using AsyncResult = std::result_of_t<std::decay_t<F>(std::decay_t<Args>...)>;
template<typename T, typename F1, typename F2>
void do_par(const std::vector<T>& ts, F1&& on_t, F2&& accumulate) {
//The standard doesn't require that these futures correspond to individual
//threads, but there's a good chance they'll be implemented that way.
std::vector<std::future<AsyncResult<F1, T>>> threads;
for (const T& t : ts) { threads.push_back(std::async(on_t, t)); }
//Think of this as just waiting on each thread to finish.
for (auto& future : threads) { accumulate(std::move(future)); }
}
template<typename T, typename F>
std::vector<AsyncResult<F, T>> map_par(const std::vector<T>& ts, F&& on_t) {
std::vector<AsyncResult<F, T>> out;
do_par(ts, on_t, [&](auto&& future_){ out.push_back(future_.get()); });
return out;
}
std::string doSomething(const std::string&){ return std::string("yo"); }
そして、あなたはこの単純なmap_par機能は非常に頭のきれるソリューションではありません
const std::vector<std::string> results = map_par(
std::vector<std::string>{".", "+", "et al"}, doSomething
);
を行うことができます。個々のスレッドを生成するオーバーヘッドを削減するスレッドキュー(スレッドプールを所有するスレッドキュー)を設定すると、CPUコアよりスレッドが多い場合に発生するコンテキスト切り替えのオーバーヘッドが助長される可能性があります。あなたのスレッドキューインプリメンテーションは、std :: asyncに似た独自のasyncメソッドを持つことができます。
入力順序に関係なく、結果がすぐに使用されるようにするには、シングル・リーダー・マルチプル・ライター(それに付随してキューを含む)を設定することを検討してください。
std :: condition_variableは、上記の両方の提案に役立ちます。
私はあなたが 'while()'ループの中で意味のある作業が行われていることを暗示していると思います。さもなければ、これは私にとって意味をなさないでしょう。 – Frank
はい、ループ内にthis_thread :: yield();を入れることができます。 –
しかし、 'get()'が返るのを待っている間、あなたのスレッドを中断してCPUを解放させることよりも、何も積極的に何もしていませんか? – Frank