It's one of the few places where code can be blocked in a system call (if you want to call a lock wait a system call -- it's close enough for me)
I'd be more upset about that if it weren't the *purpose* of lock.acquire() to block <wink>. If a user doesn't want to block, they should poll, acquire-with-timeout, or fix their bad assumptions.
I was thinking of the situation where a user learning about threads and locks gets in trouble in an interactive session, by typing something that grabs a lock that won't ever be released. Telling them they shouldn't have done that isn't going to help them. IMO this is the same kind of situation as comparing a recursive list to itself: this used to crash due to a stack overflow, and we cared enough about this "don't do that then" situation to fix it.
and a ^C doesn't stop it, and that can be annoying at times.
Of course, if it's not the main thread, signals including SIGINT shouldn't do anything, but that's a separate issue.
Why should the main thread act differently?
By fiat, only the main thread in Python is supposed to get signals.
Breaking the main thread IMO is useful behavior for interactive programs and for scripts invoked from the command line.
Being able to interrupt any thread may be useful. I guess I don't see what's especially useful about breaking the main thread. If my program is hosed, I'd just as soon kill the whole thing.
Interactively, the main thread is important.
(In practice, this is probably only interesting for interactive use -- if you hang your main thread on a deadlock, there's no way to get your prompt back, and that may mean no way to figure out what went wrong or save stuff you wanted to save.
Hmm. The "save stuff" use may be most valuable for non-interactive long-running jobs, assuming that it's possible to save stuff despite that the rest of your threads remain deadlocked (implying they're all holding *some* lock). I suppose if you can guess *which* lock the main thread broke out of, you could at least release that one and hope for some progress ...
I wasn't thinking of long-running non-interactive jobs. If you design one of those, you should know what you are doing. I was thinking of the poor interactive user who hung their interpreter by accident.
I don't know. If the possibility were there, I expect one could, with care, rely on its details to build some more-or-less useful scheme on top of it -- at least on platforms where it worked. It's really not all that attractive on its own; maybe learning how to build efficient interruptible locks x-platform could lead to a more general gimmick, though.
Yeah, unfortunately the only implementation technique I have to offer right now is to turn all acquire calls internally into a loop around an acquire call with a timeout in the order of 1 second, and to check signals each time around the loop. :-( --Guido van Rossum (home page: http://www.python.org/~guido/)