[cpp-threads] Asynchronous Execution Issues

Anthony Williams anthony at justsoftwaresolutions.co.uk
Sat Apr 25 10:10:01 BST 2009


At Fri 24 Apr 2009 21:39:11 BST, Lawrence Crowl <Lawrence at Crowl.org> wrote:

> 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 don't feel as though I have
> a mandate to propose anything that looks like a thread pool.  Do
> you agree?

No. It is up to the library when it destroys the threads. If you allow  
your task to run on a reused thread then you have to accept that the  
thread_locals may already exist because the thread has already been  
used for one or more tasks, and that the thread_locals will persist  
until the library decides to kill the thread, possibly after reusing  
the thread many times, and possibly not.

> 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.
> 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?

You don't need a special type of future. If you want to do this, you  
just need to ensure that the future value is set as the last thing the  
thread does, after destroying the thread locals. How you achieve this  
is up to the library. For example, you could have a thread_local that  
was created first and destroyed last which set the future in its  
destructor, or you could use a platform-specific API to do the same.

This would make creating_async subtly different to running a  
packaged_task on a thread. I'm not sure at the moment whether or not  
this is a good thing. I certainly see that it can be beneficial to be  
able to wait for thread_locals to be destroyed, but then again if you  
really need to that then perhaps the thread_locals are too complex.

Anthony
-- 
Anthony Williams
Author of C++ Concurrency in Action | http://www.manning.com/williams
just::thread C++0x thread library   | http://www.stdthread.co.uk
Custom Software Development         | http://www.justsoftwaresolutions.co.uk
Just Software Solutions Ltd, Registered in England, Company Number 5478976.
Registered Office: 15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK





More information about the cpp-threads mailing list