Subject: Re: [boost] Futures vs async_result
From: Niall Douglas (s_sourceforge_at_[hidden])
Date: 2015-07-27 14:18:03
On 27 Jul 2015 at 17:03, Bjorn Reese wrote:
> > Future continuations are fine when the sequence from start to end
> > doesn't branch. I am cautious of their usefulness in the general case
> > still. It isn't uncommon to make choices in a completion handler to
> > queue different async actions with different completion handlers.
> You hit the nail on the head. This is one of the main reasons why I
> seldomly use futures for asynchronous operations. Instead I prefer
> coroutines (and callbacks for simple sequences) over futures as the
> use of future continuations quickly becomes unwieldy in reality.
> async_result gives me the freedom to choose whatever mechanism is
> appropriate for my application.
I agree with this, up until C++ 1z coroutines being part of the
language. They too can work with any arbitrary synchronisation
mechanism same as async_result, however the traits specialisation to
enable an arbitrary synchronisation mechanism is rather more involved
Still, I am working under the assumption that with C++ 1z coroutines
that people have access to an async_result equivalent, so I don't
need to provide one myself.
> I suspect that Niall's preference for (his own) futures is due to
> something that has only been mentioned briefly in this discussion.
> AFIO operations are launched in a two-step process:
> 1. An operation is scheduled for execution (e.g. dispatcher::file()
> for opening a file.)
> 2. The operation is executed (e.g. dispatcher::call().)
> Using this two-step approach allows us to schedule batches of dependent
> operations before they are executed.
> When we batch operations together we should be able to express
> dependencies between them. Niall uses his own futures for that.
In the new v1.4 API things have slightly changed to become more
obvious to write for the typical programmer:
// This code uses v2 of the AFIO ABI
using namespace BOOST_AFIO_V2_NAMESPACE;
// Schedule a file open for writing
future<> fileopened=async_file("foo.txt", file_flags::write);
// Schedule a gather write to the file once it has opened
future<> filewritten=async_write(fileopened, buffers, 0);
// Schedule a fsync once the file has finished being written to
// Schedule a file close once the previous fsync has completed
All that happens asynchronously without blocking. If you'd like to
know how an operation went, simply get() its future.
In other words, the future returned carries happens-before dependency
to any operations scheduled upon that future.
Internally the above free functions quite literally expand into:
... in fact internally, under the yet to be written lightweight
futures engine, the engine itself is nothing but chains of future
-- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/