[cpp-threads] Re: Exception propogation across threads
Howard Hinnant
howard.hinnant at gmail.com
Thu Feb 22 17:54:18 GMT 2007
On Feb 22, 2007, at 10:54 AM, Matt Austern wrote:
> C++ is not the only language that has exceptions, and it will not be
> the first language that has both exceptions and threads. Is there
> any relevant experience with other languages that have both
> features? Do any of those languages ever forward an exception from
> one thread to another? If so, how well has exception forwarding
> worked in practice?
* Mac OX / gcc 4.0.1 calls terminate if a thread launched with
pthread_create has an unhandled exception.
* .NET appears to have changed behavior in this department in moving
to version 2.0 (please correct me if I'm mistaken).
http://msdn2.microsoft.com/en-us/library/ms228965(VS.80).aspx
I'm just skimming, but .NET 2.0 appears to go with what Hans
describes: catch certain exceptions such as thread_cancel, and let
others terminate the application. There are also differences between
"managed" threads and "unmanaged" threads which I will not attempt to
dissect. :-) Exceptions are made for thread pools, and other special
situations.
* Gauche (http://practical-scheme.net/gauche/man/gauche-refe_92.html)
appears to support thread propagation across threads.
* Not positive, but I believe java defaults to thread-only
termination but with a stack trace printed to the console. http://java.sun.com/docs/books/jls/second_edition/html/exceptions.doc.html
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/ThreadGroup.html#uncaughtException(java.lang.Thread,%20java.lang.Throwable)
* Boost:
> When an exception is thrown and there is no matching exception
> handler in the same thread, behavior is undefined. The preferred
> behavior is the same as when there is no matching exception handler
> in a program [15.3/9]. That is, terminate() is called, and it is
> implementation-defined whether or not the stack is unwound.
* Smalltalk? I'm getting the impression an unhandled exception from
any thread puts you in the debugger. Not positive.
Not a complete survey, but it's a start. :-)
So one possibility is the "layered approach":
A low-level std::thread (or whatever name) does not deliver results of
any kind: normal or abnormal. Unhandled exceptions (except possibly
thread_cancel) result in a call to std::terminate() (which may have a
handler by current C++03 rules). Trying to join with a canceled
thread is a sure-fire technique for dead-locking a thread. This
provides good motivation for keeping the handle of such a std::thread
non-copyable. Only one thread can "own" another, join with it, detach
it, set its priority, or cancel it.
Higher level thread abstractions (future/task) do return results which
can be normal or abnormal. Abnormal results take the form of
unhandled exceptions which have the capability to be stored/translated
across a join (the join throws), potentially to many other threads in
the case of the copyable future. Normal results take the form of a
return value on the join operation.
-Howard
More information about the cpp-threads
mailing list