I have a blocking function that I need to kill after a certain amount of time. But I have to use python2.7 for 'reasons' (sorry). I am using this to achieve what I need/
def fn(v):
try:
for i in range(v):
print(i)
time.sleep(1)
except:
print('exc!')
raise
print('done...')
t = threading.Thread(target=fn, args=(5,))
t.start()
time.sleep(3)
if t.is_alive():
print("killing", t.ident)
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(t.ident), ctypes.py_object(SystemExit))
time.sleep(3)
I let the function block for 5 seconds but I want the thread to be killed after 3 seconds. And it works like a charm in python3. But in python2, the function does not get killed and runs its course.
If I replace SystemExit
with RuntimeError
(to get a more descriptive output), this is what I get in python3, which I expect
0
1
2
killing 139879494002432
exc! # <-- NICE!
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "srv.py", line 68, in fn
time.sleep(1)
RuntimeError
But this is python2. It raises the exception but only after finishing the thread for some reason
0
1
2
killing 139903361537792
3
4
done # <-- I DON'T NEED THIS!
Unhandled exception in thread started by <bound method Thread.__bootstrap of <Thread(Thread-1, stopped 139903361537792)>>
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 774, in __bootstrap
self.__bootstrap_inner()
File "/usr/lib/python2.7/threading.py", line 849, in __bootstrap_inner
self.__stop()
File "/usr/lib/python2.7/threading.py", line 864, in __stop
self.__block.notify_all()
File "/usr/lib/python2.7/threading.py", line 407, in notifyAll
self.notify(len(self.__waiters))
File "/usr/lib/python2.7/threading.py", line 383, in notify
if not self._is_owned():
RuntimeError
Any help is highly appreciated.