Cancel Threads With An Exception

[From ExceptionsTidyThreads]

My roll-your-own thread class implements the cancel method on a thread by arranging to throw a CancelException? the next time that thread runs (which normally has the cleanup behavior PeterMerel describes). This is clean enough that even when layered over pthreads or equivalent I use this rather than their native cancel mechanisms.

The pthreads cleanup stack represents a poor person's exception handling mechanism (in C).

The Java thread interface also uses something equivalent to this, or did last I read about it, though I haven't kept track of the various versiosn of Java.

That's three, which should suffice; I'm sure there are more. --JimPerry

.Net's CLR supports this pattern. Thread.Abort causes an exception to be thrown in the thread represented by Thread. Much cleaner than Win32's TerminateThread?.

I was surprised to find that Python provides no (direct) way to cancel one running thread from another. My guess is that there must be something undesirable about cancelling other threads, but I can't think what. Any ideas? --ChrisSteinbach

Is it possible to do it in Java? It seems, as the new versions arrive, killing a thread becomes more deprecated.


It is generally not possible to inject an Exception into another thread's execution, although you may have some luck with some threads that are blocked on I/O objects but beware that you're playing with fire. It is also generally not possible in any language with VM and garbage collection that were not specifically designed to handle these thing, and of course, there's no way to safely stop or abort threads.

The reason is that such threads cannot be interrupted unless at very specific (and rare and impredictable) points when the heap is safe. Otherwise it's virtually impossible to recover form heap corruption. The inclusion of Thread.stop() and company in Java API was a terrible design mishap, because there is no basic support in the VM/language to allow a safe implementation. Needless to say that such support doesn't come for free. --CostinCozianu

Aha! So it's technical problems at a low level that prevents this. It still seems that it would be quite nice to have. Could you turn this around and say that there is a design flaw at a low level (in operating systems or thread libraries). --cs

I wouldn't call it a technical problem or design flaw, I'd call it a basic design trade-off. Providing a VM with safe-points where threads can be stopped doesn't come for free, especially when considering just in time compilation, underlying machine architecture, etc. The fact that .NET vm provides that now, may reflect the impact of evolving underlying platforms on design trade-offs (think that when Java VM was designed 100MHZ was "the next frontier", when threads started to be considered in OS design it was even less).

But there are two alternate solutions attached to this trade-off:

It's also, not only a technical implementation problem (a hard one for that matter), but it is also a logical problem, what does it mean for a thread to be cancelled by another thread ? Are we semantically safe when this happens even at the higher level than heap management (think inter object protocols, relationships and colaboration) ?

Basically all but the most basic threads are a dangerous two-edged sword, they're convenient but the underlying OS and hardware platform don't provide you with the separation and safety net, they can do for processes. So you take the benefits (higher speed, easier programming) and the risks and you have to live with both :) --cc


Costin, I think you are talking about Java. .Net is designed to support Thread.Abort safely, but MSDN says this method "usually" terminates a thread, and that the injection of the exception may be delayed until a safe point is reached. All of this uncertainty shows how tricky it is. I would only use Thread.Abort as a fallback mechanism when a more graceful thread cancellation fails to stop the thread. --IanRae

Ruby has a method thread.raise() that does this. Since Ruby has only GreenThreads?, it is always in a "safe point". That is, Ruby has only one physical thread, so its thread cancellation is just cancelling one green thread from another.


The only time I've ever had to force-quit a thread is when I'm about to do worse things than corrupt the heap anyway. - Joshua


EditText of this page (last edited May 16, 2007) or FindPage with title or text search