c++ - 函数返回的未来
问题描述
我试图理解的概念,future
但promise
有一些问题将它们用作函数的返回值。
我想出了下面的代码
#include <iostream>
#include <string>
#include <thread>
#include <future>
#include <chrono>
std::future<int> func(int i);
class A{
public:
A(std::promise<int> && prms, int i):thread_([&]{
std::cout << "Thread created in A\n";
std::this_thread::sleep_for(std::chrono::milliseconds(200));
prms.set_value(i*2);
thread_.detach();
}){std::cout << "Call constructor of A\n";}
~A(){std::cout << "Call A's Destructor\n";}
private:
std::thread thread_;
};
int main()
{
auto a_inst = func(2);
a_inst.wait();
std::cout << a_inst.get() << std::endl;
}
std::future<int> func(int i){
std::promise<int> prms;
//std::future<int> ftr = prms.get_future();
A A1(std::move(prms), i);
return prms.get_future();
}
所以main
应该从 的返回值创建一个未来func
,等待未来被分配然后打印它。但是当我执行它时,A
在没有执行线程的情况下被构造和破坏。有人可以指导我正确的方向吗?
编辑
我添加了包含不同的向量promises
。线程不直接处理,promise
而是调用processQueue
函数来完成。类A
对象被创建一次,unique_ptr 引用被传递给需要它的函数。
#include <iostream>
#include <string>
#include <thread>
#include <future>
#include <chrono>
#include <vector>
#include <mutex>
class A{
public:
int element_pointer = 0;
A():thread_([&]() {
std::cout << "Thread created in A\n";
for(;;){
std::this_thread::sleep_for(std::chrono::milliseconds(200));
processQueue();
}
//local_promise.set_value(local_i*2);
})
{
std::cout << "Call constructor of A\n";
}
~A(){
thread_.detach();
std::cout << "Call A's Destructor\n";
}
void enq(std::promise<int> prms){
std::lock_guard<std::mutex> guard(m);
local_prmses_.push_back(std::move(prms));
std::cout << "Queue now holds " << local_prmses_.size() << " elements\n";
}
private:
std::thread thread_;
std::mutex m;
std::vector<std::promise<int>> local_prmses_;
void processQueue(){
std::lock_guard<std::mutex> guard(m);
std::cout << "execute processQueue()" << std::endl;
if(element_pointer < local_prmses_.size()){
for(element_pointer; element_pointer<local_prmses_.size(); element_pointer++){
local_prmses_[element_pointer].set_value(6);
std::cout << "Promise assigned\n";
}
} else {
std::cout << "Nothing to process" << std::endl;
}
}
};
std::future<int> func(std::unique_ptr<A>& obj, int i);
int main()
{
std::unique_ptr<A> obj = std::make_unique<A>();
auto futr = func(obj, 9);
//a_inst.wait();
//std::cout << a_inst.get() << std::endl;
for(;;){
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
if(futr.valid()){
std::cout << "Yepeee!\n";
std::cout << "Result is " << futr.get() << std::endl;
}
std::cout << "waiting...\n";
}
}
std::future<int> func(std::unique_ptr<A>& obj, int i){
std::promise<int> prms;
auto fut = prms.get_future();
obj->enq(std::move(prms));
return fut;
}
解决方案
2个问题:
A
在线程可以分离之前,您正在破坏您的线程对象。例如,您可以分离 A 析构函数中的线程,因此控制流将在 A 被完全破坏之前到达它。您的线程对象中的 lambda 正在处理仅在
func
函数范围内有效的承诺。一旦控制流离开这个范围,你的 Promise 就会被破坏并抛出一个损坏的 Promise 异常。为防止这种情况发生,您的 lambda 函数应获得承诺的所有权。如果它需要所有权,您必须确保在所有权运动之前获得未来。
这导致以下代码(我刚刚删除了您的错误。它是否是一个好的设计是另一个问题;-P):
#include <iostream>
#include <string>
#include <thread>
#include <future>
#include <chrono>
std::future<int> func(int i);
class A{
public:
A(std::promise<int> prms, int i):thread_([local_promise = std::move(prms), local_i = i]() mutable {
std::cout << "Thread created in A\n";
std::this_thread::sleep_for(std::chrono::milliseconds(200));
local_promise.set_value(local_i*2);
})
{
std::cout << "Call constructor of A\n";
}
~A(){
thread_.detach();
std::cout << "Call A's Destructor\n";
}
private:
std::thread thread_;
};
int main()
{
auto a_inst = func(9);
a_inst.wait();
std::cout << a_inst.get() << std::endl;
}
std::future<int> func(int i){
std::promise<int> prms;
auto fut = prms.get_future();
A A1(std::move(prms), i);
return fut;
}
推荐阅读
- python - 无法从已从其他 Web 服务插入几秒钟的 SQL 中读取行
- regex - 使用正则表达式解析带编号的分隔字符串
- angular - 在使用 JHipster 创建的 Spring Boot 应用程序中使用 npm install 时出错
- php - 无法使用 @ParamConverter 声明自动装配实体参数
- python - PYGAME:如何碰撞 2 个类的 2 组精灵和“AttributeError: type object 'Player' has no attribute 'rect'”
- excel - 如何防止 Python 禁用现有 Excel 工作簿中的下拉列表?
- wordpress - Wordpress:长词在发送 API Restful 之前被截断
- flutter - Flutter 中来自 Google 地图的意外响应代码 400
- reactjs - 每次单击,我的 React 按钮单击记录两次
- python - 网页抓取和下载