[Python-ideas] Interrupting threads
Cameron Simpson
cs at zip.com.au
Sun Jan 27 22:04:15 CET 2013
On 27Jan2013 09:58, Charles-François Natali <cf.natali at gmail.com> wrote:
| > It's possible to interrupt the main thread using KeyboardInterrupt, so
| > why shouldn't it be possible to do something similar to a thread?
|| Because it's unsafe.
But the same can easily be true of a KeyboardInterrupt in the main
thread in any multithreaded program.
| Allowing asynchronous interruptions at any point in the code is
| calling for trouble: in a multi-threaded program, if you interrupt a
| thread in the middle of a critical section, there's a high chance that
| the invariants protected in this critical section won't hold. So
| basically, the object/structure will be in an unusable state, which
| will lead to random failures at some point in the future.
This is true if any other exception is raised also. MRAB's suggestion
turns a thread interrupt into an exception, with some control for
ignoring-but-detecting the exception around some places.
| > Actually, there's more to it than that because sometimes you don't want
| > a section of code to be interrupted.
|| Actually it's exactly the opposite: you only want to handle
| interruption at very specific points in the code, so that the rollback
| and interruption logic is tractable.
That would amount to running the whole thread inside his context manager
and polling the interrupt_occurred flag regularly.
| Also, as noted by Guido, it's basically useless because neither
| sleep() nor lock acquisition can be interrupted - at least in the
| current implementation - and those are likely the calls you'd like to
| interrupt.
Sure.
| FWIW, Java has a Thread.Stop() method that more or less does what
| you're suggesting. It was quickly depreciated because it's inherently
| unsafe: the right way to do it is through a cooperative form of
| interruption, with an interruption exception that can be thrown at
| specific points in the code (and a per-thread interrupt status flag
| that can be checked explicitly, and which is checked implicitly when
| entering an interruptible method).
| See the rationale here:
| http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
|| > So here's what I'd like to suggest:
| > 1. There's a private thread-specific flag called 'interrupt_occurred'.
| > 2. There's a private thread-specific flag called 'heeding_interrupt'.
| > 3. There's a context manager called 'heed_interrupt'.
On this basis, I'd be inclined to cast MRAB's suggestion as giving every
Thread object a cancel() method. When heeding_interrupt is True, raise
ThreadInterrupt. When heeding_interrupt is False, set
interrupt_occurred.
In fact, I'd change the word "Interrupt" to "Cancellation", and name
the flags thread_cancelled, thread_heed_cancel, and name the exception
"ThreadCancelled".
This only slightly changes the semantics and makes more clear the notion
that the cancellation may be deferred (eg when I/O blocked, etc). That
lets threads poll the thread_cancelled flag for cooperative behaviour and
still provides an exception based method for situations where it is
suitable.
| I'm not a native speaker, and I had never heard about the 'heed' verb
| before, had to look it up in the dictionary :-)
It's in common use, and not obscure. I am a native speaker, and see no
problem with it. Long standing word with a well known and defined
meaning.
Cheers,
--
Cameron Simpson <cs at zip.com.au>
Rule #1: Never sell a Ducati. Rule #2: Always obey Rule #1.
- Godfrey DiGiorgi - ramarren at apple.com - DoD #0493
More information about the Python-ideas
mailing list