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

When attaching a continuation to boost::future 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 this, and more importantly, is there a way to tweak this behavior? Do future returns from promise / packaged_task / async behave differently?

+8
c ++ multithreading boost c ++ 11
source share
2 answers

This has already been mentioned in the @ikh answer. But to make this clearer, here is a direct answer to the OP question.

You can configure whether to continue boost::future in the new thread or in the calling thread.

boost::launch policy setting specifies how the continuation should continue. See Here: Starting an Enumeration

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

The future created by async(launch::deferred, ...) or ::then(launch::deferred, ...) is related to the launch::deferred policy.

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

This should continue in the same thread.
Tested with a boost of 1.61 + Visual Studio 2015 on the Windows platform.

+3
source share

It is wise to create a new thread. Take a look at this code:

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

Without creating a new thread, we must wait for SomeVeryVeryVeryLongLongLongLongTask() in f.then(...


If you want to see certain evidence? In reference ,

  • If the parent was created with the promise <<or with packaging_task <> (does not have an associated launch policy), the continuation behaves the same as the third overload with the launch :: async | run :: delayed same argument for func.

As you know, if we use launch::async | launch::deferred launch::async | launch::deferred , we don’t know if a new thread is being generated or just being delayed. But basically a new thread is created, right?

PS. Mm? the link says "... promise <<...". This is probably the wrong type of promise<> >> o <

PS2. see @sehe answers. Strictly speaking, he is right.

-2
source share

All Articles