函数返回的未来
Future returned by a function
我试图理解 future
和 promise
的概念,但在将它们用作函数的 return 值时遇到一些问题。
我想出了下面的代码
#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
的return值创建一个未来,等待未来被分配然后打印它。
但是当我执行它时, A
在没有执行线程的情况下被构造和破坏。有人可以指导我正确的方向吗?
编辑
我添加了包含不同 promises
的向量。该线程不直接处理 promise
而是调用 processQueue
函数来处理。 class 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
函数范围内有效的承诺。一旦控制流离开这个范围,你的承诺就会被破坏并抛出一个破碎的承诺异常。为防止这种情况,您的 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;
}
我试图理解 future
和 promise
的概念,但在将它们用作函数的 return 值时遇到一些问题。
我想出了下面的代码
#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
的return值创建一个未来,等待未来被分配然后打印它。
但是当我执行它时, A
在没有执行线程的情况下被构造和破坏。有人可以指导我正确的方向吗?
编辑
我添加了包含不同 promises
的向量。该线程不直接处理 promise
而是调用 processQueue
函数来处理。 class 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
函数范围内有效的承诺。一旦控制流离开这个范围,你的承诺就会被破坏并抛出一个破碎的承诺异常。为防止这种情况,您的 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;
}