> Ive struck this a number of times, and the simple question is "can we make > it possible to interrupt a thread without the thread's knowledge" or > otherwise stated "how can we asynchronously raise an exception in another > thread?" > > The specific issue is that quite often, I find it necessary to interrupt > one thread from another. One example is Pythonwin - rather than use the > debugger hooks as IDLE does, I use a secondary thread. But how can I use > that thread to interrupt the code executing in the first? (With magic that > only works sometimes is how :-) > > Another example came up on the newsgroup recently - discussion about making > Medusa a true Windows NT Service. A trivial solution would be to have a > "service thread", that simply runs Medusa's loop in a seperate thread. > When the "service thread" recieves a shut-down request from NT, how can it > interrupt Medusa? > > I probably should not have started with a Medusa example - it may have a > solution. Pretend I said "any arbitary script written to run similarly to > a Unix daemon". There are one or 2 other cases where I have wanted to > execute existing code that assumes it runs stand-alone, and can really only > be stopped with a KeyboardInterrupt. I can't see a decent way to do this. > > [I guess this ties into the "signals and threads" limitations - I believe > you cant direct signals at threads either?] > > Is it desirable? Unfortunately, I can see that it might be hard :-( > > But-sounds-pretty-easy-under-those-fake-threads<wink>-ly, Hmm... Forget about signals -- they're twisted Unixisms (even if they are nominally supported on NT). The interesting thing is that you can interrupt the "main" thread easily (from C) using Py_AddPendingCall() -- this registers a function that will be invoked by the main thread the next time it gets to the top of the VM loop. But the mechanism here was designed with a specific purpose in mind, and it doesn't allow you to aim at a specific thread -- it only works for the main thread. It might be possible to add an API that allows you to specify a thread id though... Of course if the thread to be interrupted is blocked waiting for I/O, this is not going to interrupt the I/O. (On Unix, that's what signals do; is there an equivalent on NT? I don't think so.) Why do you say that your magic only works sometimes? You mailed me your code once and the Python side of it looks okay to me: it calls PyErr_SetInterrupt(), which calls Py_AddPendingCall(), which is threadsafe. Of course it only works if the thread you try to interrupt is recognized by Python as the main thread -- perhaps this is not always under your control, e.g. when COM interferes? Where is this going? Is the answer "provide a C-level API like Py_AddPendingCall() that takes a thread ID" good enough? Note that for IDLE, I have another problem -- how to catch the ^C event when Tk is processing events? --Guido van Rossum (home page: http://www.python.org/~guido/)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4