[Python-3000] threading, part 2

Josiah Carlson jcarlson at uci.edu
Sat Aug 12 11:07:29 CEST 2006

"Marcin 'Qrczak' Kowalczyk" <qrczak at knm.org.pl> wrote:
> Josiah Carlson <jcarlson at uci.edu> writes:
> > Threading is already difficult enough to do 'right' (see the dozens
> > of threads discussing why this is really the case), and designing
> > software that can survive the raising of an exception at any point
> > makes threading even more difficult.
> That's why I'm proposing to provide ways to limit those "any points".
> > I believe that you are attempting to design an interface to make
> > this particular feature foolproof.
> No, I'm merely attempting to make it usable.
> You are proposing to make it unusable?
> Indeed, you are proposing to make it unusable.

Because you or anyone else can define a standard mechanism of handling
these points where threads are allowed to be killed, and you can publish
it on the internet via the Python cookbook, etc., having nothing in the
standard library specifically supporting the operation isn't making
anything unusable.

I'm not proposing to make it unusable, merely that it should not be made
any easier to use.  See Nick Coughlan's comment with regards to '...easy
things easy...'.

> > I believe that if a user cannot design and implement their own
> > system to handle when a thread can be killed or not to their own
> > satisfaction, then they have no business killing threads.
> I have already implemented it. In my own language, where I have
> full control over the runtime.

I'm glad that you have managed to implement it in your programming
language.  But this discussion isn't about Kogut, Haskell, etc., this is
about Python.  Specifically what should and should not be available in
the Python standard library.

I've said it before, but apparently the following point is ignored, so
I'll say it again.  The 'kill thread' mechanism isn't available via some
threading.kill_thread(thr) function because Guido and other core
developers *of* Python do not want it to be generally acceptable for
users to kill arbitrary threads.  The introduction of methods of
controlling where a thread could be killed into the standard library
would be encouraging the 'kill thread' usage.

It would be far safer (and much less work for the developers of Python)
for users to just learn how to handle thread quitting using any of the
standard methods of doing so (check the value of a variable, wait for a
signal, etc.).

Never mind that any feature is going to have to wait 18+ months before
Python 2.6 comes out in order to get your proposed changes in.

> Now it would be nice if Python had usable asynchronous exceptions too.

Python has had usable asynchronous exceptions since Python 2.3 [1].

> If we are not brave enough, we can implement at least an equivalent
> of POSIX thread cancellation. It would be better than nothing, though
> not as useful, because the default mode allows interruption only at
> certain blocking primitives. In this scenario Unix signals need a
> different policy so a pure computation not performing I/O nor thread
> synchronization can be interrupted; Unix signals usually cause the
> whole process to abort so data integrity was less of a concern.
> A language with GC and exceptions can do better, with a unified policy
> for thread cancellation and Unix signals and other asynchronous events.
> It can be done such that well-written libraries are safely interruptible
> even if exceptions may occur almost anywhere. Protection should be
> built into certain operations (e.g. try...finally extended with an
> "initially" clause, or taking a mutex), so that there is less work
> needed to make code safe to be interrupted; then quite often it's
> already safe.

I don't have much of a comment with regards to attempted unification of
signals, etc., as Windows signal handling is effectively useless (and my
primary development platform tends to be Windows).

 - Josiah

Python 2.3.5 (#62, Feb  8 2005, 16:23:02) [MSC v.1200 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> import threading
>>> import time
>>> def foo():
...     try:
...             while 1:
...                     time.sleep(.01)
...     finally:
...             print "I quit!"
>>> x = threading.Thread(target=foo)
>>> x.start()
>>> for i,j in threading._active.items():
...     if j is x:
...             break
>>> ctypes.pythonapi.PyThreadState_SetAsyncExc(i, ctypes.py_object(Exception))
>>> I quit!
Exception in thread Thread-2:Traceback (most recent call last):
  File "C:\python23\lib\threading.py", line 442, in __bootstrap
  File "C:\python23\lib\threading.py", line 422, in run
    self.__target(*self.__args, **self.__kwargs)
  File "<stdin>", line 4, in foo

More information about the Python-3000 mailing list