何时使用过异步或packaged_task承诺? [英] When to use promise over async or packaged_task?
问题描述
当我应该使用的std ::承诺
在的std ::异步
或 STD :: packaged_task
?
你能给我什么时候使用他们中的每一个实际的例子吗?
When should I use std::promise
over std::async
or std::packaged_task
?
Can you give me practical examples of when to use each one of them?
推荐答案
的std ::异步
一>是一个整洁和简单的方法来得到一个 的std ::未来
,但是:
std::async
std::async
is a neat and easy way to get a std::future
, but:
-
不总是启动一个新的线程;通过
的std ::推出::异步
作为第一个参数,迫使它。
Not always it starts a new thread; pass
std::launch::async
as a first parameter to force it.
auto f = std::async( std::launch::async, func );
的的std ::〜未来
的析构函数的可以的块,直到新线程完成
the std::~future
destructor can block until new thread finishes
auto sleep = [](int s) { std::this_thread::sleep_for(std::chrono::seconds(s)); };
{
auto f = std::async( std::launch::async, sleep, 5 );
}
通常情况下,我们预计,仅获得()
或 .wait()
块,但为的std ::未来
从的std ::异步
的析构函数也可能会阻止,所以要小心,不要只是忘记阻止你的主线程一下吧。
Normally we expect that only .get()
or .wait()
blocks, but for std::future
returned from std::async
destructor also may block, so be careful not to block your main thread just by forgetting about it.
如果在的std ::未来
存储在一个临时的生活目标,的std ::异步
调用将阻塞现货,所以下面块将采取的自动F =
初始化:
if the std::future
is stored in a temporary-life object, std::async
call will block on spot, so the following block will take 10 seconds if you remove the auto f =
initializations:
auto sleep = [](int s) { std::this_thread::sleep_for(std::chrono::seconds(s)); };
{
auto f1 = std::async( std::launch::async, sleep, 5 );
auto f2 = std::async( std::launch::async, sleep, 5 );
}
的std :: packaged_task
一>本身无关,与线程:它只是一个仿函数和相关的未来。考虑以下几点:
std::packaged_task
by itself has nothing to do with threads: it is just a functor and a related future. Consider the following:
auto task = [](int i) { std::this_thread::sleep_for(std::chrono::seconds(5)); return i+100; };
std::packaged_task< int(int) > package{ task };
std::future<int> f = package.get_future();
package(1);
std::cout << f.get() << "\n";
在这里,我们只需要运行由任务包(1)
,并返回后,˚F
已就绪所以没有阻塞获得()
。
Here we just run the task by package(1)
, and after it returns f
is ready so no blocking on .get()
.
不过:一个特点使packaged_task线程非常有用的。相反,只是一个功能,你可以初始化的std ::线程
用packaged_task。考虑以下 - packaged_task是获得未来的一个非常好的方式:
But: one feature make the packaged_task very useful for threads. Instead of just a function you can initialize std::thread
with a packaged_task. Consider the following - packaged_task is a really nice way of getting future:
std::packaged_task< int(int) > package{ task };
std::future<int> f = package.get_future();
std::thread t { std::move(package), 5 };
std::cout << f.get() << "\n"; //block here until t finishes
t.join();
的std :: packaged_task
是不可拷贝,所以你将其与的std ::移动
移动到新的任务。
std::packaged_task
is not copyable, so you move it to new task with std::move
.
的std ::承诺
一>是一个强有力的机制,例如,你可以将值传递给新的线程,而无需任何额外的同步机制。
std::promise
is a powerful mechanism, for example you can pass a value to new thread without need of any additional synchronizing mechanism.
auto task = [](std::future<int> i) {
std::cout << i.get() << std::flush;
};
std::promise<int> p;
std::thread t{ task, p.get_future() };
std::this_thread::sleep_for(std::chrono::seconds(5));
p.set_value(5);
t.join();
新的线程将等待我们获得()
所以,总的来说,回答你的问题:
So, in general, answering your question:
- 使用
的std ::异步
只是简单的东西,比如要在心中有些通话无阻塞,但熊上面挡住了意见。 -
使用
的std :: packaged_task
来轻松搞定未来,并运行它作为一个单独的线程
- use
std::async
only to simple things, for example to make some call non-blocking, but bear in mind the comments on blocking above. use
std::packaged_task
to easily get future, and run it as a separate thread
std::thread{ std::move(package), param }.detach();
或
std::thread t { std::move(package), param };
使用的std ::承诺
当你需要在未来更多的控制权。
use std::promise
when you need more control over the future.
另请参阅 的std :: shared_future
并在线程之间传递异常<一个href=\"http://en.cp$p$pference.com/w/cpp/thread/promise/set_exception\"><$c$c>std::promise::set_exception$c$c>
这篇关于何时使用过异步或packaged_task承诺?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!