
On Thu, Jun 27, 2013 at 9:01 PM, Vicente J. Botet Escriba
mailto:vicente.botet@wanadoo.fr> wrote: Le 27/06/13 14:26, Tobias Furuholm a écrit :
I am trying out future<>.then and I am seeing some results that confuses me. I have tried to illustrate this with a few examples. The first example is using a promise together with future<>.then. It generates no output:
boost::promise<int> promise; boost::future<int> fut = promise.get_future(); promise.set_value(123);
fut.then([](boost::future<int>& f) { std::cout << "The value is: " << f.get() << std::endl; return f.get(); });
boost::chrono::milliseconds duration(1000); boost::this_thread::sleep_for(duration);
Why is fut.then not triggered? (assigning fut.then to another future makes no difference)
I guess you need to call fut.then() before the value is set. I will need to check if this works when the future is not created with async().
It makes no difference. Sorry I was wrong. There is an issue with the current implementation. If the parent future has not been created with async, you need to add the launch policy on
Le 27/06/13 22:53, Tobias Furuholm a écrit : the then call. Please, could you add a ticket to the Trac system? I will try to fix it soon.
By adding a launch policy I get the output "The value is: 123" which is the output I would expect from all my examples:
boost::promise<int> promise; boost::future<int> fut = promise.get_future();
promise.set_value(123);
fut.then(boost::launch::async, [](boost::future<int>& f) { std::cout << "The value is: " << f.get() << std::endl; return f.get(); });
boost::chrono::milliseconds duration(1000); boost::this_thread::sleep_for(duration);
Could you tell me the version of BOOST_THREAD_VERSION are you using?
I use BOOST_THREAD_VERSION=4
To make this more real, let's move promise.set_value to after .then
boost::promise<int> promise; boost::future<int> fut = promise.get_future();
fut.then(boost::launch::async, [](boost::future<int>& f) { std::cout << "The value is: " << f.get() << std::endl; return f.get(); });
promise.set_value(123);
boost::chrono::milliseconds duration(1000); boost::this_thread::sleep_for(duration);
This program outputs nothing and never terminates. But when I assign the result of fut.then to another future I get the expected output once again:
boost::promise<int> promise; boost::future<int> fut = promise.get_future();
*boost::future<int> fut2* = fut.then(boost::launch::async, [](boost::future<int>& f) { std::cout << "The value is: " << f.get() << std::endl; return f.get(); });
promise.set_value(123);
boost::chrono::milliseconds duration(1000); boost::this_thread::sleep_for(duration);
Where is the assignment?
I made the assignment bold to make it more visible...
When you use a policy launch::async the resulting future will block on the destructor. When there is no assignment the temporary is destroyed before the promise is set.
Again I will need to check this.
Finally, as I bonus I add an example where I use async to generate a future instead.
boost::future<int> fut = boost::async([]() { return 123; });
fut.then([](boost::future<int>& f) { std::cout << "The value is: " << f.get() << std::endl; return f.get(); });
boost::chrono::milliseconds duration(1000); boost::this_thread::sleep_for(duration);
future::get() can be called only once depending on the value of BOOST_THREAD_VERSION
This generates the output "The value is: " (without 123). Once again, by assigning the result of fut.then to another future I get the expected output.
As the fut shared state is set asynchronously the temporary ends by been set, so the trace is done. Thanks, Vicente