Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2007-03-26 18:32:58


On Mar 26, 2007, at 6:10 PM, Stefan Seefeld wrote:

> Roland Schwarz wrote:
>> Howard Hinnant wrote:
>>
>>> I swear (lays hand on backup disk) on my backup disk, all N2184 (and
>>
>>> N2178 as I understand it) wants of C++ cancellation is to request
>>> that
>>
>>> the target thread (whenever it gets around to it, if ever) throw a
>>
>>> normal C++ exception, which the target thread is free to
>>> subsequently
>>
>>> catch, swallow and digest. :-)
>>
>> To be honest. I did not yet had time to study N2184 and 2178.
>> But if this is true, wouldn't this be in contradiction to pthread
>> semantics? Wouldn't this users rather confuse even more?
>
> Indeed, I think these are two very different things:
>
> 1) Request a thread cancelation.
>
> This is what in POSIX threads is called pthread_cancel(), and what
> you
> presumably mean by "t.raise(cancel_exception)".
>
> 2) Notify that a thread has been canceled.
>
> This is what would presumably result in a thread_canceled exception
> being thrown.
>
> As far as I understand, the desired semantics here would be
> 'deferred',
> i.e. 1) is really only a request, i.e. at the point this call returns
> there is no guarantee that the cancellation has been terminated (or
> even initialized).
>
> Note that you suggested "t.raise(std::thread_canceled)", which sounds
> misleading, since 'canceled' suggests this is raised at the point
> where the cancelation is finished, not requested.
>
> For that matter I don't really see the point in using an exception
> to signal the 'cancel request' to the target thread, while the use
> of an exception in 2) makes a lot of sense, since the main discussion
> (as far as POSIX threads & C++ is concerned) is about the cleanup,
> i.e.
> the missing stack unwinding semantics.
>
> (Part of the discussion is about whether the exception can be
> caught without being rethrown in handlers such as 'catch (...) {}',
> or whether catch(...) should see thread_canceled at all, etc.)

Beman was supposed to pipe up by now. :-) He has suggested
"request_cancel()" or "request_cancellation()" to replace "cancel()"
to make it absolutely clear this is a request, not an imperative. I
prefer the shorter "cancel()", but it is definitely not an "over my
dead body" issue for me (nor is it I think for Beman).

I am not aware of anyone in C++ circles who is currently recommending
anything other than the "request" semantics. There are people on the
posix committee however who think we're nuts for wanting to allow
threads to catch their own cancellation exception. Thus the problem
with delegating to pthread_cancel...

My killer use case for the catchable cancel is a thread_pool library:

Such a library would execute a small number of threads, and hold a
queue of waiting tasks which get assigned to a thread when one is
available. Clients of thread_pool can insert tasks into the queue,
and when they do so they receive back a handle (which I'll call
future) through which they can join with, or cancel, the inserted task.

If the client decides to cancel the task, this translates into an
exception being thrown in the running thread. Up in the start function
which wraps/adapts the user-supplied function, that exception is
caught, and the still running thread is returned to idle status in the
thread_pool, ready to accept another task from the pool's queue.

One might wonder if thread cancellation is the right semantics for
this action. Perhaps some other exception could be thrown. The
disadvantage with this is that the task might need to catch/rethrow
the cancellation exception during clean up as it is being canceled.
It would be a shame if it needed to watch for two different flavors of
cancellation to do this (one kind if you're executing in a regular
thread, another kind if you're executing in a thread pool).

One could design the thread_pool to let such canceled tasks continue
to cancel the underlying thread. The thread_pool could be alerted to
this fact and simply start a new thread to replace the canceled one.
Imho, this would be inelegant, and inefficient by comparison.

Fwiw, here's a link to the cancellation description in N2184:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2184.html#Examples

Search for "Canceling threads" once you hit the link. It is little
more than a page of examples and description (not a formal spec).

-Howard


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk