I try to understand the concept of future
and promise
but have some issues to use them as return values from functions.
I came up with the code below
#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();
}
So main
should create a future from the return value of func
, wait for the future to be assigned and then print it.
But when I execute it, A
is constructed and destructed without the thread being executed. Could someone guide me to the right direction?
edit
I added the vector containing the different promises
. The thread doesn't directly process the promise
but calls the processQueue
function to do it. The class A
object is created once and a unique_ptr reference is handed to the function where it's required.
#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;
}