Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does boost::future<T>::then() spawn a new thread?

When attaching a continuation to boost::future, the continuation is executed in a new thread:

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

This snippet outputs:

main: 0x7fff7a8d7310
future: 0x101781000

Why is .then() allowed to do that, and, more importantly, is there a way to customise this behaviour? Do futures returned from promise/packaged_task/async behave differently?

like image 390
marton78 Avatar asked Apr 08 '14 10:04

marton78


1 Answers

It is already mentioned in @ikh answer. But to make it more clear, here is the direct answer to the OP question.

It is customizable whether boost::future continuation should be executed in a new thread or in the calling thread.

boost::launch policy parameter specifies how the continuation should run. See here: Enumeration launch

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

A future created by async(launch::deferred, ...) or ::then(launch::deferred, ...) has associated a launch policy launch::deferred.

So, try running this:

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

That should run the continuation in the same thread.
Tested with boost 1.61 + Visual Studio 2015 on Windows platform.

like image 95
Alexander Stepaniuk Avatar answered Nov 03 '22 00:11

Alexander Stepaniuk