我對未來和承諾之間的差異感到困惑。期貨與承諾
顯然,他們有不同的方法和東西,但實際的用例是什麼?
是不是?:
- 當我管理的一些異步任務,我用未來的「未來」來獲取值
- 當我異步任務,我用的承諾作爲返回類型以允許用戶從我的承諾中獲得未來
我對未來和承諾之間的差異感到困惑。期貨與承諾
顯然,他們有不同的方法和東西,但實際的用例是什麼?
是不是?:
Future和Promise是異步操作的兩個獨立方面。
std::promise
被異步操作的「生產者/寫入者」使用。
std::future
被異步操作的「消費者/讀者」使用。
它被分成這兩個單獨的「接口」的原因是hide「消費者/閱讀器」的「寫入/設置」功能。
auto promise = std::promise<std::string>();
auto producer = std::thread([&]
{
promise.set_value("Hello World");
});
auto future = promise.get_future();
auto consumer = std::thread([&]
{
std::cout << future.get();
});
producer.join();
consumer.join();
一個(不完全)的方式來實現的std ::異步使用std ::承諾可能是:
template<typename F>
auto async(F&& func) -> std::future<decltype(func())>
{
typedef decltype(func()) result_type;
auto promise = std::promise<result_type>();
auto future = promise.get_future();
std::thread(std::bind([=](std::promise<result_type>& promise)
{
try
{
promise.set_value(func()); // Note: Will not work with std::promise<void>. Needs some meta-template programming which is out of scope for this question.
}
catch(...)
{
promise.set_exception(std::current_exception());
}
}, std::move(promise))).detach();
return std::move(future);
}
使用std::packaged_task
這是一個輔助(即它基本上做什麼我們做以上)各地std::promise
你可以做的是更完整,更可能更快如下:
template<typename F>
auto async(F&& func) -> std::future<decltype(func())>
{
auto task = std::packaged_task<decltype(func())()>(std::forward<F>(func));
auto future = task.get_future();
std::thread(std::move(task)).detach();
return std::move(future);
}
注意,這是從std::async
略有不同其中返回的std::future
將在被銷燬時實際阻塞,直到線程完成。
@taras表明返回'std :: move(something)'是無用的,它也會傷害(N)RVO。恢復他的編輯。 –
在Visual Studio 2015中,請使用std :: cout << future.get()。c_str(); – Damian
對於那些仍然困惑,請參閱[這個答案](http://stackoverflow.com/questions/11004273/what-is-stdpromise/12335206#12335206)。 –
我寫了一個關於這個[在這個答案](http://stackoverflow.com/a/12335206/596781)。 –
[什麼是std :: promise?](http://stackoverflow.com/questions/11004273/what-is-stdpromise) –