[Python-3000] threading, part 2
Tim Peters
tim.peters at gmail.com
Mon Aug 14 21:15:30 CEST 2006
[tomer filiba]
>> i mailed this to several people separately, but then i thought it could
>> benefit the entire group:
>>
>> http://sebulba.wikispaces.com/recipe+thread2
>>
>> it's an implementation of the proposed " thread.raise_exc",
>> ...
[Guido]
> Cool. Question: what's the problem with raising exception instances?
See
http://mail.python.org/pipermail/python-dev/2006-August/068165.html
Short course: in ceval.c,
x = tstate->async_exc;
...
PyErr_SetNone(x);
That is, with the current code it's only possible to set the exception
type via PyThreadState_SetAsyncExc(); the exception value is forced to
None/NULL. What was the intent ;-)?
Example:
"""
from time import sleep
import ctypes, thread, sys, threading
setexc = ctypes.pythonapi.PyThreadState_SetAsyncExc
f_done = threading.Event()
def f():
try:
while 1:
time.sleep(1)
finally:
f_done.set()
tid = thread.start_new_thread(f, ())
exc = ValueError("13")
setexc(ctypes.c_long(tid),
ctypes.py_object(exc))
f_done.wait()
"""
Output:
Unhandled exception in thread started by <function f at 0x009E8370>
Traceback (most recent call last):
File "setexc.py", line 12, in f
f_done.set()
File "C:\Code\python\lib\threading.py", line 351, in set
self.__cond.release()
SystemError: 'finally' pops bad exception
Change `exc` to, e.g.,
exc = ValueError
and then it's fine:
Unhandled exception in thread started by <function f at 0x009E8370>
Traceback (most recent call last):
File "setexc.py", line 12, in f
f_done.set()
File "C:\Code\python\lib\threading.py", line 349, in set
self.__cond.notifyAll()
File "C:\Code\python\lib\threading.py", line 265, in notifyAll
self.notify(len(self.__waiters))
File "C:\Code\python\lib\threading.py", line 258, in notify
waiter.release()
ValueError
More information about the Python-3000
mailing list