我把自己与未来和承诺之间的区别混淆了.
显然,他们有不同的方法和东西,但实际的用例是什么?
是吗?:
可能重复:
使用成员函数启动线程
我有一个小班:
class Test
{
public:
void runMultiThread();
private:
int calculate(int from, int to);
}
Run Code Online (Sandbox Code Playgroud)
如何在方法的两个线程中calculate使用两个不同的参数集(例如calculate(0,10),calculate(11,20))运行方法runMultiThread()?
PS谢谢我忘记了我需要传递this,作为参数.
我正在尝试建立一些启发式方法来帮助我确定std::thread要使用的适当类.
据我了解,从最高级别(最简单到使用,但最不灵活)到最低级别,我们有:
我想我对何时使用前两个有一个很好的把握,但我仍然不清楚std::promise.
std::future与std::async调用一起,有效地将生成的回调/函数/ lambda转换为异步调用(根据定义,它立即返回).一个单一的消费者可以拨打std::future::get()阻止电话,以获得结果.
std::shared_future 只是一个允许多个消费者的版本.
如果要将std::future值与生成器回调绑定,但希望将实际调用推迟到以后(将任务关联到生成线程时),std::packaged_task则是正确的选择.但是现在,由于对应std::future于std::package_taskcan,在一般情况下,可以由多线程访问,我们可能必须小心使用a std::mutex.请注意std::async,在第一种情况下,我们不必担心锁定.
阅读了一些关于承诺的有趣链接,我想我理解它的机制以及如何设置它们,但我的问题是,你什么时候会选择使用其他三个承诺呢?
我正在寻找一个应用程序级别的答案,比如一个经验法则(填写上面的???),而不是链接中的答案(例如使用std :: promise来实现一些库机制),所以我可以更容易地解释如何为初级用户选择合适的类std::thread.
换句话说,这将是很好有什么我可以用做一个有用的例子std::promise是不能与其他机制来完成.
回答
A std::future是一种奇怪的野兽:一般来说,你不能直接修改它的值.
可以修改其价值的三个生产者是:
std::async通过异步回调,它将返回一个std::future实例.std::packaged_task,当传递给线程时,将调用其回调,从而更新std::future与之关联的实例std::packaged_task.此机制允许生成器的早期绑定,但稍后调用.std::promise,允许std::future通过其 …我知道了future返回的原因std::async有一些特殊的共享状态,通过它wait on returned future发生在未来的析构函数中。但是当我们使用 时std::pakaged_task,它的未来不会表现出相同的行为。为了完成任务打包,你必须显式调用get()上future的对象packaged_task。
现在我的问题是:
std::async与std::packaged_task)的内部实现可能是什么?futurereturn from std::packaged_task?或者,换句话说,相同的行为是如何停止的std::packaged_task future?要查看上下文,请查看以下代码:
它不会等待完成countdown任务。但是,如果我取消评论// int value = ret.get();,它就会结束countdown并且很明显,因为我们实际上是在阻止返回的未来。
// packaged_task example
#include <iostream> // std::cout
#include <future> // std::packaged_task, std::future
#include <chrono> // std::chrono::seconds
#include <thread> // std::thread, std::this_thread::sleep_for
// count down taking a second for each value:
int countdown (int from, …Run Code Online (Sandbox Code Playgroud) std :: promise提供了一种设置值(类型为T)的方法,稍后可以通过关联的std :: future对象读取该值
这两者究竟如何相关联?
我的担忧是否合理,未来会与错误的承诺结合?
更新:来自行动中的并发的示例...(但代码无法编译)
#include <future>
void process_connections(connection_set& connections)
{
while(!done(connections)){
for(connection_iterator
connection=connections.begin(),end=connections.end();
connection!=end;
++connection)
{
if(connection->has_incoming_data()){
data_packet data=connection->incoming();
std::promise<payload_type>& p=
connection->get_promise(data.id);
p.set_value(data.payload);
}
if(connection->has_outgoing_data()){
outgoing_packet data=
connection->top_of_outgoing_queue();
connection->send(data.payload);
data.promise.set_value(true);
}
}
}
}
Run Code Online (Sandbox Code Playgroud) 在花了一些时间使用 C++/CX 和 ++/WinRT 开发简单的 UWP 应用程序后,我开始享受针对该环境进行 Windows UI 应用程序开发的一些功能。
现在必须回到更熟悉的 MFC 应用程序开发,我想将我的方法更改为类似于 UWP 应用程序开发的方法。其想法是使用异步 C++11 线程生成内容并修改 MFC UI 中显示的内容。
我想要做的主要更改是使用 C++11 线程来卸载一些耗时的任务,并使这些线程将结果传达回主 MFC UI。
我希望卸载到 C++11 线程上的一些任务(与我在 UWP 应用中使用 C++/CX 和 C++/WinRT 的异步任务使用的任务类似)是:
我遇到的问题与我在 MFC 中可以有多个 GUI 线程吗?中描述的问题类似。但是,我正在寻找一种通用方法,而不是该问题中的具体进度条更新。
我一直在尝试使用 Visual Studio 模板对实验性 MFC 应用程序进行简单测试,该模板在左侧停靠有一个树控件,以在工作线程中构建树。
如果我有一个CViewTree显示树视图的 MFC 窗口,我想从 C++11 线程更新该窗口,那么我当前正在使用它::PostMessage()来请求更新停靠窗格中的树控件。
如果我将 lambda 与全局一起使用,std::thread例如以下代码:
std::thread t1;
void CClassView::FillClassView()
{
// ::SendMessage() seems to deadlock …Run Code Online (Sandbox Code Playgroud)