[thread] request for interest in new c++1y features

Hi, I would like to include some of the new thread/future proposed features included in N3428: A Standard Programmatic Interface for Asynchronous (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3428.pdf). What do you think? Best, Vicente

Vicente J. Botet Escriba <vicente.botet <at> wanadoo.fr> writes:
Hi,
I would like to include some of the new thread/future proposed features included in N3428: A Standard Programmatic Interface for Asynchronous (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3428.pdf).
What do you think?
Best, Vicente
I would have a use for these, and I would like to see these implemented. Contact me if you want any help. Evan Wallace

On 2012-10-20 12:40, Vicente J. Botet Escriba wrote:
I would like to include some of the new thread/future proposed features included in N3428: A Standard Programmatic Interface for Asynchronous (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3428.pdf).
The future.then proposal looks very useful. It is unclear to me, however, what happens if the async call returns before .then is hooked up. Will the .then function be executed in the calling thread?

Bjorn Reese <breese <at> mail1.stofanet.dk> writes:
The future.then proposal looks very useful.
It is unclear to me, however, what happens if the async call returns before .then is hooked up. Will the .then function be executed in the calling thread?
The answer to this depends on the situation. The paper states that "The continuation launches according to the specified policy or scheduler". I would interpret this to mean that the continuation is run as if by a call to std::async in the first thread to have both a .then continuation set and a value available (so -- in the .then thread if the future already contains a result at the time of the call to .then, and in the thread that fills the future, if the future did not yet contain a result when .then was called). Evan Wallace

Le 20/10/12 15:45, Bjorn Reese a écrit :
On 2012-10-20 12:40, Vicente J. Botet Escriba wrote:
I would like to include some of the new thread/future proposed features included in N3428: A Standard Programmatic Interface for Asynchronous (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3428.pdf).
The future.then proposal looks very useful.
It is unclear to me, however, what happens if the async call returns before .then is hooked up. Will the .then function be executed in the calling thread?
Yes, as I understand it then() checks if the future is already ready as otherwise it will never be notified of the change and call then to the continuation function on the calling thread. Do you see any problems with this approach? Best, Vicente

On 2012-10-20 17:47, Vicente J. Botet Escriba wrote:
Le 20/10/12 15:45, Bjorn Reese a écrit :
It is unclear to me, however, what happens if the async call returns before .then is hooked up. Will the .then function be executed in the calling thread?
Yes, as I understand it then() checks if the future is already ready as otherwise it will never be notified of the change and call then to the continuation function on the calling thread. Do you see any problems with this approach?
The main problem is the duration of the continuation. If the function passed to std::async finishes before we call future.then, then the continuation will be executed by the calling thread. This means that the calling thread is blocked while the continuation is executed, which is a problem if the continuation is slow. Then we might as well call the two functions synchroneously. Evan pointed out that this can be handled with a custom scheduler, although I must admit that I am uncertain how. Anyways, having to define a scheduler seems like a like a complex workaround to address this problem. My preferred solution would be to first call std::async with std::launch::deferred, then set up the future.then continuations, and finally start the execution. This would require an extension to std::future (e.g. a future.launch function) that starts the execution without blocking, as future.wait or future.get does.

Bjorn Reese <breese <at> mail1.stofanet.dk> writes:
The main problem is the duration of the continuation. If the function passed to std::async finishes before we call future.then, then the continuation will be executed by the calling thread. This means that the calling thread is blocked while the continuation is executed, which is a problem if the continuation is slow. Then we might as well call the two functions synchroneously.
My understanding is that the continuation will be *launched from* the calling thread, but the thread on which the continuation is *actually run* is determined by the launch policy. Perhaps an example will help to explain what I mean by this: #include <future> using namespace std; int main() { //Compute some value on a different thread. //The launch policy defaults to launch::async | launch::deferred future<int> f1 = async([]() { return 123; }); //Call wait() to ensure that this example hits the situation //where the .then call occurs after the future is already //available. f1.wait(); //The continuation will be run (as if) by std::async, //and so will not block the current thread if an //appropriate launch policy is selected. //The launch policy is inherited from the original //async call (unless explicitly overridden). future<int> f2 = f1.then([](future<int> f) { return expensive_computation(f.get()); }); } Evan Wallace

Le 21/10/12 15:41, Evan Wallace a écrit :
Bjorn Reese <breese <at> mail1.stofanet.dk> writes:
The main problem is the duration of the continuation. If the function passed to std::async finishes before we call future.then, then the continuation will be executed by the calling thread. This means that the calling thread is blocked while the continuation is executed, which is a problem if the continuation is slow. Then we might as well call the two functions synchroneously. My understanding is that the continuation will be *launched from* the calling thread, but the thread on which the continuation is *actually run* is determined by the launch policy. Perhaps an example will help to explain what I mean by this:
#include <future> using namespace std; int main() { //Compute some value on a different thread. //The launch policy defaults to launch::async | launch::deferred future<int> f1 = async([]() { return 123; });
//Call wait() to ensure that this example hits the situation //where the .then call occurs after the future is already //available. f1.wait();
//The continuation will be run (as if) by std::async, //and so will not block the current thread if an //appropriate launch policy is selected. //The launch policy is inherited from the original //async call (unless explicitly overridden). future<int> f2 = f1.then([](future<int> f) { return expensive_computation(f.get()); }); }
I see. I missed the inheritance from the original. Unfortunately the Boost.Thread futures implementation doesn't stores yet the way the future was created and so I'm unable to implement this as such. I have a task pending, implement async with launch::deferred. Once I could take in account the inheritance of the launch policy. Until that I could use the launch::async policy instead of calling the continuation on the same thread. Thanks for your interesting comments, Vicente
participants (3)
-
Bjorn Reese
-
Evan Wallace
-
Vicente J. Botet Escriba