为什么boost :: future <t> :: then()会产生一个新线程?</t>

时间:2014-04-08 10:42:16

标签: c++ multithreading c++11 boost

将续集附加到boost::future时,将在新线程中执行继续:

std::cout << "main: " << boost::this_thread::get_id() << std::endl;

boost::promise<void> p;
boost::future<void> f = p.get_future();
p.set_value();

boost::future<void> f2 = f.then([] (boost::future<void>) {
    std::cout << "future: " << boost::this_thread::get_id() << std::endl;        
});

此代码段输出:

main: 0x7fff7a8d7310
future: 0x101781000

为什么.then()允许这样做,更重要的是,有没有办法自定义此行为?从future / promise / packaged_task返回的async行为有何不同?

2 个答案:

答案 0 :(得分:4)

在@ikh的回答中已经提到了。但为了更清楚,这是OP问题的直接答案。

可自定义boost::future延续是否应在新线程或调用线程中执行。

boost::launch policy参数指定延续的运行方式。见这里:{{3}}

enum class launch
{
    none = unspecified,
    async = unspecified,
    deferred = unspecified,
    executor = unspecified,
    inherit = unspecified,
    any = async | deferred
};
  

async(launch::deferred, ...)::then(launch::deferred, ...)创建的未来与启动政策launch::deferred相关联。

所以,试试这个:

boost::future<void> f2 = f.then(
    boost::launch::deferred,
    [] (boost::future<void>&&) {
        std::cout << "future: " << boost::this_thread::get_id() << std::endl;        
    }
);

那应该在同一个线程中运行延续 在Windows平台上使用boost 1.61 + Visual Studio 2015进行测试。

答案 1 :(得分:-2)

生成一个新线程是合理的。看看这段代码:

std::cout << "main: " << boost::this_thread::get_id() << std::endl;

boost::promise<void> p;
boost::future<void> f = p.get_future();
p.set_value();

boost::future<void> f2 = f.then([] (boost::future<void>) {
    SomeVeryVeryVeryLongLongLongLongTask();

    std::cout << "future: " << boost::this_thread::get_id() << std::endl;        
});

如果没有产生新主题,我们必须在SomeVeryVeryVeryLongLongLongLongTask()等待f.then(...


如果您想查看某些证据?在reference

  • 如果使用promise创建父级&lt;&lt;或者使用packaged_task&lt;&gt; (没有关联的启动策略),延续行为与第三次重载相同,其策略参数为launch :: async | launch :: deferred和func的相同参数。

如您所知,如果我们使用launch::async | launch::deferred,我们不知道是否生成了新线程,或者只是延迟了它。但是大多数情况都会产生一个新线程,对吗?

PS。嗯?引用说“... promise&lt;&lt; ...”。也许这是promise<>&gt; o&lt;

的错误类型

PS2。看@ sehe的回复。严格地说,他是对的。

相关问题