c++ - 使用promise和future将值从子线程传递给主线程
问题描述
我试图使用未来和承诺以异步方式将数据从主线程发送到子线程。这是代码。
#include <bits/stdc++.h>
using namespace std;
int sampleFunc(vector<future<int>> &f) {
int a = f[0].get();
cout <<"got a from promise 1" << endl;
int b = f[1].get();
cout <<"got b from promise 2" << endl;
return a + b;
}
int main() {
int outputVal;
int k = 2;
std::vector<promise<int>> p(k);
vector<future<int>> f(k);
f[0] = p[0].get_future();
f[1] = p[1].get_future();
std::future<int> fu = std::async(std::launch::async,sampleFunc,std::ref(f));
std::this_thread::sleep_for(chrono::milliseconds(1000));
p[0].set_value(2);
std::this_thread::sleep_for(chrono::milliseconds(3000));
p[1].set_value(4);
outputVal = fu.get();
cout << outputVal << endl;
}
延迟可能有其他含义,例如 和 的值a
可能b
还没有准备好(可能我们正在等待其他一些任务在主线程中发生)。
也就是说,如何将部分数据(异步,如上例)从子线程传递到主线程?这种数据传输模型能否扩展到其他线程(子线程到另一个子线程)?
谢谢 !
解决方案
您可以使用“经典解决方案”在线程之间共享数据:shared_ptr
. 我不认为promise
并且future
可以(通常)用于传输部分数据:“请注意,std::promise 对象只能使用一次。” (cppreference.com:这里)。我修改了你的代码(一点点)来表明我的观点,如果有麻烦请回来:
#include "bits/stdc++.h"
using namespace std;
// only a string, but a structure is more general
struct Transfer {
std::string m_status;
Transfer() noexcept {};
Transfer(const std::string& status) : m_status(status)
{};
};
// std::atomic_shared_ptr is a (new) alternative to this use of std::shared_ptr
// warning: atomic functions for shared pointers do work on the shared
// pointer, not on the contained data
int sampleFunc(vector<future<int>> &f, std::shared_ptr<Transfer>& status) {
std::atomic_store(&status, std::make_shared<Transfer>("Waiting for the first result ..."));
int a = f[0].get();
std::this_thread::sleep_for(chrono::milliseconds(100)); // to "sync" the output
cout << "got a from promise 1" << endl;
std::atomic_store(&status, std::make_shared<Transfer>("Waiting for the second result ..."));
int b = f[1].get();
std::this_thread::sleep_for(chrono::milliseconds(100)); //to "sync" the output
cout << "got b from promise 2" << endl;
std::atomic_store(&status, std::make_shared<Transfer>("Finishing ..."));
std::this_thread::sleep_for(chrono::seconds(1));
return a + b;
}
int main() {
int outputVal;
int k = 2;
std::vector<promise<int>> p(k);
vector<future<int>> f(k);
f[0] = p[0].get_future();
f[1] = p[1].get_future();
std::shared_ptr<Transfer> status_shared = std::make_shared<Transfer>("Started");
// do not forget to use std::ref
std::future<int> fu = std::async(std::launch::async, sampleFunc, std::ref(f), std::ref(status_shared));
const auto wait_for_1 = std::async(std::launch::async, [](promise<int>& p) {
std::this_thread::sleep_for(chrono::milliseconds(1000));
p.set_value(2);
}, std::ref(p[0]));
const auto wait_for_2 = std::async(std::launch::async, [](promise<int>& p) {
std::this_thread::sleep_for(chrono::milliseconds(3000));
p.set_value(4);
}, std::ref(p[1]));
do {
const auto status = std::atomic_load(&status_shared);
cout << status->m_status << '\n';
} while (future_status::timeout == fu.wait_for(chrono::seconds(1)));
outputVal = fu.get();
cout << outputVal << endl;
return 0;
}
推荐阅读
- graphql - 根据折扣检索产品
- powershell - 无法使用 powershell 构建 docker 映像?
- c# - 各种 NuGet 包中的 Azure CloudStorageAccount 命名空间冲突,以及迁移到较新的 Azure SDK
- python - 更改另一个变量时如何更新实例变量?
- php - Varnish POST 缓存无法通过 PHP CURL 工作,但是,它似乎与 TERMINAL CURL 一起工作
- javascript - JavaScript - 输入值未定义
- python - Pandas 根据另一列中的输入创建具有特定值的列
- twilio - 分机拨号时StatusCallBack的处理
- c# - 出了点问题,请从 BotFramework MessagingExtesion 重试
- python-3.x - 如何在while循环python中写入csv文件