[Python-3000] threading, part 2

Nick Coghlan ncoghlan at gmail.com
Wed Aug 9 12:45:08 CEST 2006

Jim Jewett wrote:
> On 8/8/06, tomer filiba <tomerfiliba at gmail.com> wrote:
>> my previous suggestion asked for is a means to raise exceptions in the
>> context of *other* threads.
> ...
>> * breaking the thread's state -- that's not really an issue. i'm not talking
>> about *forcefully* killing the thread, without cleanup.
> This has the same inherent problem as Java's Thread.stop -- that data
> shared beyond the thread may be left in an inconsistent state because
> the cleanup wasn't done, perhaps because a lock was held.
> https://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
>> so it's may seem brute to suggest a mechanism that raises exceptions
>> at arbitrary points in your code-flow, but:
> If you're willing to forget about native code (and you suggested that
> you were), then you could just check[*] every N bytecodes, the way the
> interpreters already checks to decide whether it should switch
> threads.  Whether the performance overhead is worthwhile is a
> different question.

That check is already there:

int PyThreadState_SetAsyncExc(	long id, PyObject *exc)
     Asynchronously raise an exception in a thread. The id argument is the 
thread id of the target thread; exc is the exception object to be raised. This 
function does not steal any references to exc. To prevent naive misuse, you 
must write your own C extension to call this. Must be called with the GIL 
held. Returns the number of thread states modified; if it returns a number 
greater than one, you're in trouble, and you should call it again with exc set 
to NULL to revert the effect. This raises no exceptions. New in version 2.3.

In Python 2.5, you can use ctypes to get at the whole C API from Python code, 
and calling thread.get_ident() in the run() method will allow you to find out 
the thread id of your thread (you'll need to save that value somewhere so 
other code can get at it).

All Tober is really asking for is a method on threading.Thread objects that 
uses this existing API to set a builtin ThreadExit exception. The thread 
module would consider a thread finishing with ThreadExit to be 
non-exceptional, so you could easily do:

   th.terminate() # Raise ThreadExit in th's thread of control
   th.join() # Should finish up pretty quickly

Proper resource cleanup would be reliant on correct use of try/finally or with 
statements, but that's the case regardless of whether or not asynchronous 
exceptions are allowed.


Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-3000 mailing list