When attaching a continuation to boost::future
, the continuation is executed in a new thread:
当附加一个continuation to 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;
});
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 future
s returned from promise
/packaged_task
/async
behave differently?
为什么then()被允许这样做,更重要的是,是否有一种方法可以定制这种行为?从承诺/packaged_task/async返回的期货有不同的行为吗?
2 个解决方案
#1
3
It is already mentioned in @ikh answer. But to make it more clear, here is the direct answer to the OP question.
在@ikh的回答中已经提到了。但为了更清楚地说明这一点,这里是OP问题的直接答案。
It is customizable whether boost::future
continuation should be executed in a new thread or in the calling thread.
可以自定义boost::将来的continuation应该在新线程或调用线程中执行。
boost::launch
policy parameter specifies how the continuation should run. See here: Enumeration launch
boost::启动策略参数指定延续应该如何运行。看到:枚举发射
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 policylaunch::deferred
.异步创建的未来(launch: deferred,…)或:::然后(launch: deferred,…)关联了一个启动策略:::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.
它应该在相同的线程中运行延续。在Windows平台上使用boost 1.61 + Visual Studio 2015进行测试。
#2
-2
It is reasonable to spawn a new thread.. 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 spawning a new thread, we have to wait for SomeVeryVeryVeryLongLongLongLongTask()
at f.then(...
.
没有生成一个新线程,我们必须等待SomeVeryVeryVeryLongLongLongLongTask()在f.then(....
If you want to see certain evidence? In reference,
如果你想看到某些证据?在参考,
- If the parent was created with promise<< or with a packaged_task<> (has no associated launch policy), the continuation behaves the same as the third overload with a policy argument of launch::async | launch::deferred and the same argument for func.
- 如果父类是使用promise< <或使用packaged_task<> (没有相关的启动策略)创建的,那么continuation的行为与第三个包含launch的策略参数的重载相同:::async | launch::deferred以及func的相同参数。
As you know, if we use launch::async | launch::deferred
, we don't know whether a new thread is spawned or just it's deferred. But mostly a new thread is spawned, right?
如您所知,如果我们使用launch::async |启动::延迟,我们不知道是否生成了新线程,或者只是延迟了。但大多数情况下都是新线程生成的,对吧?
PS. Um? reference say "...promise<<...". Maybe it's a mistype of promise<>
>o<
PS。嗯?参考说“…< <承诺…”。可能是承诺的错误类型<> >o<
PS2. see @sehe's replies. Strictly speaking, he's right.
PS2。看到@sehe答道。严格地说,他是对的。
#1
3
It is already mentioned in @ikh answer. But to make it more clear, here is the direct answer to the OP question.
在@ikh的回答中已经提到了。但为了更清楚地说明这一点,这里是OP问题的直接答案。
It is customizable whether boost::future
continuation should be executed in a new thread or in the calling thread.
可以自定义boost::将来的continuation应该在新线程或调用线程中执行。
boost::launch
policy parameter specifies how the continuation should run. See here: Enumeration launch
boost::启动策略参数指定延续应该如何运行。看到:枚举发射
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 policylaunch::deferred
.异步创建的未来(launch: deferred,…)或:::然后(launch: deferred,…)关联了一个启动策略:::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.
它应该在相同的线程中运行延续。在Windows平台上使用boost 1.61 + Visual Studio 2015进行测试。
#2
-2
It is reasonable to spawn a new thread.. 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 spawning a new thread, we have to wait for SomeVeryVeryVeryLongLongLongLongTask()
at f.then(...
.
没有生成一个新线程,我们必须等待SomeVeryVeryVeryLongLongLongLongTask()在f.then(....
If you want to see certain evidence? In reference,
如果你想看到某些证据?在参考,
- If the parent was created with promise<< or with a packaged_task<> (has no associated launch policy), the continuation behaves the same as the third overload with a policy argument of launch::async | launch::deferred and the same argument for func.
- 如果父类是使用promise< <或使用packaged_task<> (没有相关的启动策略)创建的,那么continuation的行为与第三个包含launch的策略参数的重载相同:::async | launch::deferred以及func的相同参数。
As you know, if we use launch::async | launch::deferred
, we don't know whether a new thread is spawned or just it's deferred. But mostly a new thread is spawned, right?
如您所知,如果我们使用launch::async |启动::延迟,我们不知道是否生成了新线程,或者只是延迟了。但大多数情况下都是新线程生成的,对吧?
PS. Um? reference say "...promise<<...". Maybe it's a mistype of promise<>
>o<
PS。嗯?参考说“…< <承诺…”。可能是承诺的错误类型<> >o<
PS2. see @sehe's replies. Strictly speaking, he's right.
PS2。看到@sehe答道。严格地说,他是对的。