[cpp-threads] Asynchronous Execution Issues

Lawrence Crowl Lawrence at Crowl.org
Sat Apr 25 08:37:57 BST 2009


On 4/24/09, Boehm, Hans <hans.boehm at hp.com> wrote:
> > 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?
>
> Interesting and disconcerting observation.
>
> Is there any reason to believe that if the current future doesn't
> work for this, it works for anything else?  My inclination would
> be to fix what's there, if it's broken.

I think that the futures we have will work fine with thread pools
because the destruction of the pool itself can signal the
destruction of the threads.

> This sounds to me like a serious problem in the current draft,
> which is highlighted by creating_async.  It's not something we
> should work around in creating_async.

> I'm not quite sure I understand exactly which one of several
> problem scenarios you're worried about here.  Presumably the
> child thread sets the promise, and then exits without additional
> library calls.  I think the intent was to make a thread that
> behaves this way (i.e. that makes a synchronization call to the
> library to indicate it is done and then exits) safe in the sense
> that it is guaranteed not to race with destruction of static
> objects needed by the standard library (guarantee A).  I can no
> longer find a statement to that effect.  But I think we need
> such a guarantee if we ever want to safely shut down a detached
> thread (in the sense of making it safe to call exit() rather
> than quick_exit()).
>
> Without destructors for thread_local variables, I think this can
> be made to work.  But I'm not sure that guarantee A is acheivable
> in the presence of arbitrary thread_local destructors, at least
> the way we had envisioned.

I think it is achievable, so long as we can wait on the child
thread.  Once we return from the wait call, we can be sure that
the child thread has completed all its destructors.

> And even if we fix this case (by having exit() wait for detached
> threads ???), I'm still worried about destructors for thread
> locals that refer to automatic variables on the parent stack.
> I think most people's reaction is "don't do that".  But I'm not
> convinced it can reasonably be avoided, if I have nontrivial
> destructors for thread_locals at all.

My example doesn't refer to variables in the call stack, though
I admit that the code appears that way at first glance.

Anyway, I was thinking of a fix in which another future type
also did a wait on the thread in addition to providing the return
value.  That mechanism neatly handles the destruction of thread
locals.

-- 
Lawrence Crowl



More information about the cpp-threads mailing list