Yes, I also wonder about how non-CPython implementations would handle this but I'd just like to say that this feature, making a thread raise a specific exception from another thread asynchronously is a very useful feature.
We have a subsystem that schedules requests that are dispatched in a thread each. The only way to cancel one of those requests right now is via a cooperative checking method in which we explicitly make calls through out the code to see if the request has been canceled, and in such case, the check raises an exception that triggers clean up and cancellation. Problem is we have to spread check calls all over the place. All this would be a lot easier if we could do thread.terminate() as proposed, especially for new code. On 8/9/06, "Guido van Rossum" wrote: > On 8/9/06, Tim Peters <[EMAIL PROTECTED]> wrote: > > [Nick Coghlan] > > >> That check is already there: > > >> > > >> int PyThreadState_SetAsyncExc( long id, PyObject *exc) > > >> Asynchronously raise an exception in a thread. The id argument is > > >> the > > >> thread id of the target thread; exc is the exception object to be > > >> raised. This > > >> function does not steal any references to exc. To prevent naive misuse, > > >> you > > >> must write your own C extension to call this. Must be called with the GIL > > >> held. Returns the number of thread states modified; if it returns a > > >> number > > >> greater than one, you're in trouble, and you should call it again with > > >> exc set > > >> to NULL to revert the effect. This raises no exceptions. New in version > > >> 2.3. > > > > Guido, do you have any idea now what the "number greater than one" > > business is about? That would happen if and only if we found more > > than one thread state with the given thread id in the interpreter's > > list of thread states, but we're counting those with both the GIL and > > the global head_mutex lock held. My impression has been that it would > > be an internal logic error if we ever saw this count exceed 1. > > Right, I think that's it. I guess I was in a grumpy mood when I wrote > this (and Just & Alex never ended up using it!). > > > While I'm at it, I expect: > > > > Py_CLEAR(p->async_exc); > > Py_XINCREF(exc); > > p->async_exc = exc; > > > > is better written: > > > > Py_XINCREF(exc); > > Py_CLEAR(p->async_exc); > > p->async_exc = exc; > > > > for the same reason one should always incref B before decrefing A in > > > > A = B > > > > ... > > That reason that A and B might already be the same object, right? > > > >> All Tober is really asking for is a method on threading.Thread objects > > >> that > > >> uses this existing API to set a builtin ThreadExit exception. The thread > > >> module would consider a thread finishing with ThreadExit to be > > >> non-exceptional, so you could easily do: > > >> > > >> th.terminate() # Raise ThreadExit in th's thread of control > > >> th.join() # Should finish up pretty quickly > > >> > > >> Proper resource cleanup would be reliant on correct use of try/finally > > >> or with > > >> statements, but that's the case regardless of whether or not asynchronous > > >> exceptions are allowed. > > > > [Guido] > > > I'm +0 on this. > > > > Me too, although it won't stay that simple, and I'm clear as mud on > > how implementations other than CPython could implement this. > > Another good reason to keep it accessible from the C API only. Now I'm > -0 on adding it. I suggest that if someone really wants this > accessible from Python, they should research how Jython, IronPython, > PyPy and Stackless could handle this, and report their research in a > PEP. > > -- > --Guido van Rossum (home page: http://www.python.org/~guido/) > > -- Luis P Caamano Atlanta, GA USA _______________________________________________ Python-3000 mailing list [email protected] http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com
