Issue1167930
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2005-03-21 22:19 by nveeser, last changed 2022-04-11 14:56 by admin. This issue is now closed.
Messages (6) | |||
---|---|---|---|
msg24747 - (view) | Author: Nicholas Veeser (nveeser) | Date: 2005-03-21 22:19 | |
I write a python program that that starts several threads and then waits on them all. If I use join() to wait on the threads, there is no way to Stop the process with Ctrl-C. Threading.Thread.join() uses a lock (thread.allocate_lock()) to put itself on the "wait_queue". It then calls thread.Lock.acquire(), which blocks indefinitely. Lock.acquire() (at least in POSIX) seems to work in such a way as to ignore any signals. (both semaphore and condition variable type). PyThread_acquire_lock() will not return until the lock is acquired, even if a signal is sent. Effectively, Ctrl-C is "masked" until the lock is released, (the joined thread is done), and the main thread comes back to the interpreter and handles the signal, producing a KeyboardInterrupt Exception. But not before the lock is released, which is once the thread is finished, which is too late if you want to kill the main thread and have it gracefully stop its child threads. So the "main" thread has no way to call, join() and still respond to Ctrl-C in some way. One solution could be to change threading.Thread.join() to use other methods of synchronization which respond to Ctrl-C more effectively. Another solution would be to have Lock.acquire() throw a KeyboardInterruped exception like other system calls. This IHMO would make the python objects behave more like Java, which requires catching the InterruptedException, giving the developer more control over how to handle this case. |
|||
msg24748 - (view) | Author: Peter Hansen (phansen) | Date: 2005-03-26 14:59 | |
Logged In: YES user_id=567267 Coincidentally this issue came up in a thread in comp.lang.python just now. See tim one's reply at 1111815188.1799.python-list%40python.org">http://groups.google.ca/groups?selm=mailman.884.1111815188.1799.python-list%40python.org which indicates that "it's simply not possible for Ctrl+C to interrupt a mutex acquire". A workaround is to be sure to call join() with a timeout value, inside a loop if you absolutely need an indefinite timeout, but that won't necessarily work because of a different problem which I just reported as bug 1171023. There's a workaround for that problem too though, provided you can subclass threading.Thread: provide your own join() which wraps the builtin one and which attempts to release the lock safely. I'll attach an example if I can figure out how... there's no option to do so on this particular page in Sourceforge. :-( |
|||
msg24749 - (view) | Author: Peter Hansen (phansen) | Date: 2005-03-26 15:22 | |
Logged In: YES user_id=567267 It appears only the original submitter (and admins?) can attach files, so I've attached the example workaround in the other bug report that I submitted. It makes more sense in that one anyway. |
|||
msg24750 - (view) | Author: Brett Cannon (brett.cannon) * | Date: 2005-03-27 19:02 | |
Logged In: YES user_id=357491 The other bug report phansen is talking about is bug #1171023 (http:// www.python.org/sf/1171023). Closed as a duplicate but it can still be used for file uploads by phansen. Also worth reading for its explanation. |
|||
msg24751 - (view) | Author: Stephen Gildea (gildea) * | Date: 2007-07-28 15:20 | |
The workaround of calling join() with a timeout has a drawback: Python's threading wait routine polls 20 times a second when given any timeout. All this polling can mean lots of CPU interrupts/wakeups on an otherwise idle laptop and drain the battery faster. |
|||
msg56947 - (view) | Author: Guido van Rossum (gvanrossum) * | Date: 2007-10-30 00:56 | |
This is because the regular acquire() method on a basic lock cannot be interrupted. That's unlikely to go away, so you'll just have to live with this. As you've discovered, specifying a timeout solves the issue (sort of). |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:56:10 | admin | set | github: 41740 |
2007-10-30 00:56:32 | gvanrossum | set | status: open -> closed nosy: + gvanrossum resolution: wont fix messages: + msg56947 |
2005-03-21 22:19:14 | nveeser | create |