[cpp-threads] Asynchronous Execution Issues

Bjarne Stroustrup bs at cs.tamu.edu
Fri Apr 24 21:56:22 BST 2009


Lawrence Crowl wrote:
> At the Summit meeting I took the action item of producing a proposal
> for a simple asynchronous execution.  The idea was to facilities,
> with an API along the lines of:
>
>     auto x = std::creating_async( function1 );
>     auto y = std::caching_async( function2 );
>     ....
>     auto a = x.get();
>     auto b = y.get();
>
> The difference between the two is that creating_async would always
> create a new thread, while the caching_async is permitted to reuse
> threads.  The primary operational difference is that thread-local
> storage is reused in the latter case.
>   

This is great! I was about to write something along those lines myself 
(thinking that I was
among those such charged - and seriously behind with my work as usual)

Naming is a big deal: I don't think those two names are good.

Also, I don't think the key issue is/was whether a thread might be 
reused, but whether a task
might be executed on the thread that launched it. In that spirit, I 
propose the names:
    async()   // execute somewhere
    async_thread()   // execute on a thread different from that of the 
launcher

(is it async() of asynch() and why?)

> There are a couple of issues that make the task more difficult than
> we thought at the time.  As a result, I have a couple of questions.
>
> First, consider the case of the caching_async.  Because the threads
> may persist, we need a handle on the list of threads so that we
> can inform a thread to die so that we destroy any thread-local
> variables before the global variables that they reference.  So, we
> start needing a manager object, and the whole facility is starting
> to look too much like a thread pool. 

I'm not convinced that's necessary. It's up to whoever implements 
async_thread() to
    (1) make sure that a task gets a "clean" thread (with no information 
from previous tasks
    in local variables)
    (2) a terminal error on an asynch_tread()ed tread is reflected in 
its future and
    the thread is properly killed or recycled.
I think that exposing any details of how/if/when that is done is against 
the spirit of asynch.

>  I don't feel as though I have
> a mandate to propose anything that looks like a thread pool.  Do
> you agree?
>   

Agreed.

> Second, consider the case of the creating_async.  The problem here
> is a touch more subtle.  In particular, once the working thread has
> set its promise, it can start destroying thread-local variables.
>   

You are making too many assumptions here. My mental model is that the 
tread is clean when
a task starts executing. It couldn't possible know about the local 
variables of a previous task.

> Unfortunately, we have no idea when that has or might happen.
> That thread could be stalled immediately after providing the value.
> The solution is to wait for thread termination before returning the
> value from the future.  This solution implies keeping the thread as
> part of the future so that we can wait.  We have no such mechanism.
> So, an asynchronous execution function needs another kind of future.
> Is such a future going beyond my mandate?
>
>   

Sorry to be so brief, but I am just finishing the semester, etc., and I 
think that the solution to these
problems is to specify simply what must be done and carefully avoid 
saying how it is done.





More information about the cpp-threads mailing list