Killing threads (was Re: Cancel or timeout a long running regular expression)

Cameron Simpson cs at zip.com.au
Sat Sep 17 19:23:38 EDT 2011


On 17Sep2011 15:27, Chris Rebert <clp2 at rebertia.com> wrote:
| On Sat, Sep 17, 2011 at 2:35 PM, Chris Angelico <rosuav at gmail.com> wrote:
| > On Sun, Sep 18, 2011 at 5:00 AM, Nobody <nobody at nowhere.com> wrote:
| >> The only robust solution is to use a separate process (threads won't
| >> suffice, as they don't have a .kill() method).
| >
| > Forking a thread to discuss threads.... ahem.
| >
| > Why is it that threads can't be killed? Do Python threads correspond
| > to OS-provided threads (eg POSIX threads on Linux)? Every OS threading
| > library I've seen has some way of killing threads, although I've not
| > looked in detail into POSIX threads there (there seem to be two
| > options, pthread_kill and pthread_cancel, that could be used, but I've
| > not used either). If nothing else, it ought to be possible to
| > implement a high level kill simply by setting a flag that the
| > interpreter will inspect every few commands, the same way that
| > KeyboardInterrupt is checked for.
| >
| > Is it just that nobody's implemented it, or is there a good reason for
| > avoiding offering this sort of thing?
| 
| It's possible that the reason is analogous to why Java has deprecated
| its equivalent, Thread.stop():
| http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

Interesting. A lot of that discussion concerns exceptions that the Java
app is unprepared for. Java's strong typing includes the throwable
exceptions, so that's a quite legitimate concern. The aborting mutex
regions thing is also very real. Conversely, Python can have unexpected
exceptions anywhere, anytime because it is not strongly typed in this
way. That doesn't make it magicly robust against this, but does mean
this is _already_ an issue in Python programs, threaded or otherwise.

Context managers can help a lot here, in that they offer a reliable
exception handler in a less ad hoc fashion than try/except because it
is tied to the locking object; but they won't magicly step in save
your basic:

  with my_lock:
    stuff...

Personally I'm of the view that thread stopping should be part of the
overt program logic, not a low level facility (such as causing a
ThreadDeath exception asynchronously). The latter has all the troubles
in the cited URL. Doing it overtly would go like this:

  ... outside ...
  that_thread.stop()    # sets the "stopping" flag on the thread object
  that_thread.join()    # and now maybe we wait for it...

  ... thread code ...
  ... do stuff, eg:
  with my_lock:
    muck about ...
  if thread.stopping:
    abort now, _outside_ the mutex
  ...

This avoids the issue of aborting in the middle of supposedly mutex-safe
code. It still requires scattering checks on thread.stopping through
library code such as the OP's rogue regexp evaluator.

Cheers,
-- 
Cameron Simpson <cs at zip.com.au> DoD#743
http://www.cskk.ezoshosting.com/cs/

One measure of `programming complexity' is the number of mental objects you
have to keep in mind simultaneously in order to understand a program.  The
mental juggling act is one of the most difficult aspects of programming and
is the reason programming requires more concentration than other activities.
It is the reason programmers get upset about `quick interruptions' -- such
interruptions are tantamount to asking a juggler to keep three balls in the
air and hold your groceries at the same time.
        - Steve McConnell, _Code Complete_



More information about the Python-list mailing list