期货是检查单个线程完成的安全方法吗?

时间:2012-08-23 00:17:17

标签: c++ multithreading boost thread-safety

我一直在玩Boost的未来,并且想知道它们是否是一种可接受且安全的方式来检查个别线程是否已经完成。

我之前从未使用过它们,所以我编写的大部分代码都基于Boost's 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.这可能出错吗?

谢谢!

2 个答案:

答案 0 :(得分:4)

是的,期货以这种方式使用是安全的,并且(快速浏览)代码是安全和正确的。

还有其他方法可以执行相同的操作(例如,使用atomic_flag或受互斥锁保护的数据,或许多其他方法),但您的代码是一种有效的方法。

N.B。而不是f.is_ready()this_thread::sleep(seconds(1))您可以使用f.wait_for(seconds(1)),一旦结果准备就会唤醒。这将直接等待未来,而不是检查未来,然后等待使用单独的机制,然后检查,然后等待单独的机制等。

而不是packaged_taskthread,您可以使用async

使用C ++ 11名称代替boost ...

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;
}

答案 1 :(得分:2)

  

我一直在玩Boost的未来,并且想知道它们是否是一种可接受且安全的方式来检查个别线程是否已经完成。

期货是异步评估的机制,而不是同步机制。虽然某些基元确实具有同步属性(future<>::get),但该库并非设计为同步,而是触发任务并忽略它直到需要结果。