1

私は Boost の先物をいじっていましたが、個々のスレッドが完了したかどうかを確認するための受け入れ可能で安全な方法であるかどうか疑問に思っていました.

以前にそれらを使用したことがなかったので、私が書いたコードのほとんどはBoost の Synchronization documentationに基づいていました。

#include <iostream>
#include <boost/thread.hpp>
#include <boost/thread/future.hpp>

int calculate_the_answer_to_life_the_universe_and_everything()
{
    boost::this_thread::sleep(boost::posix_time::seconds(10));
    return 42;
}

int main()
{
    boost::packaged_task<int> task(calculate_the_answer_to_life_the_universe_and_everything);
    boost::unique_future<int> f(task.get_future());

    boost::thread th(boost::move(task));

    while(!f.is_ready())
    {
        std::cout << "waiting!" << std::endl;
        boost::this_thread::sleep(boost::posix_time::seconds(1));
    }

    std::cout << f.get() << std::endl;

    th.join();
}

これは、calculate_the_answer_to_life_the_universe_and_everything() スレッドが 42 を返すのを待っているようです。

ありがとう!

4

2 に答える 2

4

はい、先物はそのように使用しても安全であり、コードは(一目で)安全で正しいです。

同じことを行う方法は他にもありますが (たとえば、atomic_flag、またはミューテックスで保護されたデータを使用するなど)、コードは有効な方法です。

f.is_ready()代わりにNB をthis_thread::sleep(seconds(1))使用できますf.wait_for(seconds(1))。これは、結果が準備されるとすぐにウェイクします。これは、未来をチェックしてから別のメカニズムを使用して待機し、次にチェックしてから別のメカニズムで待機するのではなく、未来を直接待機します。

と の代わりに をpackaged_task使用threadできますasync

ブーストの代わりに C++11 名を使用する ...

int main()
{
    auto f =  std::async(std::launch::async, calculate_the_answer_to_life_the_universe_and_everything);

    while(f.wait_for(std::chrono::seconds(1)) == std::future_status::timeout)
        std::cout << "waiting!" << std::endl;

    std::cout << f.get() << std::endl;
}
于 2012-08-23T00:56:17.650 に答える
2

私は Boost の先物をいじくり回してきましたが、個々のスレッドが完了したかどうかを確認するための受け入れ可能で安全な方法であるかどうか疑問に思っていました.

Future は非同期評価のメカニズムであり、同期メカニズムではありません。一部のプリミティブには同期プロパティ ( future<>::get) がありますが、ライブラリは同期するようには設計されておらず、むしろタスクを起動し、結果が必要になるまで無視するように設計されています。

于 2012-08-23T00:29:56.550 に答える