[cpp-threads] Asynchronous Function Proposal

Herb Sutter hsutter at microsoft.com
Wed Jun 17 06:16:29 BST 2009


Attached is a first draft of my paper that's a complement/competitor to N2889.

Comments and criticisms are welcome!


Brief responses to Lawrence (most other responses are in the paper, and may or may not be correct so please let me know if I got anything egregiously or tinily wrong):

Thanks Lawrence,

> >   - The async policy parameter is still first, and we don't need
> >   a variadic overload. There should be just one async() with a
> >   defaulted policy parameter.
> 
> I have no objection to this approach a-priori, but I think the
> async parameters should be consistent with the thread constructor
> parameters.  If thread changes, the async should change as well.

I don't see what you're referring to in 30.3 (looking at N2857). Is there a separate paper adding constructor parameters? I don't see "fully_threaded" etc. anywhere.


> >   - The wording for the first policy still says "in a new thread,"
> >   which prevents the implementation from caching threads in any way
> >   (including the highly desirable option of running on a thread
> >   pool). It should say "in another thread."
> 
> N2880 says why allowing thread caching is not feasible.  We can do
> caching when we have thread pools, but I don't believe that we can
> do so until then.

Maybe I'm missing something: I don't see how this is specific to async so as to influence the async design. As Peter and others have pointed out, this use-after-destruction issue has nothing to specifically with async, nor even specifically with threads at all, but is a general and preexisting issue with globals and statics. Am I justified in taking a "nothing to see here" view? I don't want to be wrongly dismissive, but I don't see what those (valid) issues have to do with async.

See further notes in the attached.


> BTW, the OS can still cache threads underneath, but it still has
> to destroy and reconstruct the thread-local variables.
> 
> >   - There is still a new future type, async_future. It should be
> >   unique_future.  (In related news, the return type of async()
> >   should be convertible to shared_future. Adding a conversion
> >   from async_future to shared_future would satisfy that part,
> >   but not satisfy the main point in this bullet.)
> 
> Can you provide a rationale based on use cases?

Anything that uses a shared_future is a use case. As I mentioned recently, the key is that we want to pass a value somewhere, and sometimes the target needs the value immediately and sometimes it needs it eventually. From my note on 6/3:

- Anytime the result is of interest to more than one thread. You
- don't want to block-then-share, you want to pass everyone a future
- so everyone can keep running concurrently until they need the
- result. In dataflow terms, think of any example where we split the
- pipe two or more ways.


> > > The proposed solution consists of a set of async functions
> > > to launch asychronous work and a new kind of future to
> > > manage the function result.  This solution derives from
> > > an extensive discussion on the C++ threads standardisation
> > > <cpp-threads at decadentplace.org.uk> mailing list.
> >
> > That wrongly implies that the discussion blessed/suggested both the
> > "set of async functions" and "a new kind of future" design points
> > -- both of which I and others have objected to. At minimum this
> > needs to acknowledge that there were strong objections against
> > both of these features.
> 
> Note that I said discussion, not consensus.  It was my intent to
> capture the discussion and choices in the document.  If you feel
> that I have not done so accurately, please send me text.

Add something like: "In that discussion there were strong objections to both the 'set of async functions' and particularly to 'a new kind of future' design points proposed in this paper." (For now I've put in a placeholder objection to this in the attached but desire to remove it.)


> Unfortunately, packaged tasks and futures are only part of the
> specification.  The issues presented in N2880 are handled in the
> code around those primitives.  That is, by providing a set of very
> primitive mechanisms, packaged task et al punt on the hard issues.
> By introducing async, we are squeezing out that code, and hence
> need to address those issues.

If you think that my comments in the attached on N2880 are missing something, I'd really like to understand it and could you explain what it is?


Notes on your proposal's proposed wording:

- several places still talk about a policy type, that should be 'enumerator' now

- is the final note really true?


Thanks,

Herb

-------------- next part --------------
A non-text attachment was scrubbed...
Name: async.doc
Type: application/msword
Size: 61440 bytes
Desc: async.doc
URL: <http://www.decadentplace.org.uk/pipermail/cpp-threads/attachments/20090616/305c7c6f/attachment-0001.doc>


More information about the cpp-threads mailing list