在Python开发(http://www.maiziedu.com/course/python-px/)中,由于经常被Python非Daemon线程阻塞,导致程序无法结束。所以向找个方法能强制关闭线程就好了,可是在网上找了很多方法都不能解决问题,可能是在MAC上面试验的,可是皇天不负有心人,终于找到了最终解决方法,详细情况见代码:
import threading
import time
import inspect
import ctypes
def _async_raise(tid, exctype):
"""raises the exception, performs cleanup if needed"""
tid = ctypes.c_long(tid)
if not inspect.isclass(exctype):
exctype = type(exctype)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
if res == 0:
raise ValueError("invalid thread id")
elif res != 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
def stop_thread(thread):
_async_raise(thread.ident, SystemExit)
class TestThread(threading.Thread):
def run(self):
print "begin"
while True:
time.sleep(0.1)
print "end"
if __name__ == "__main__":
t = TestThread()
t.start()
time.sleep(1)
stop_thread(t)
print "stoped"
改造后的方案,只是在 _async_raise 函数最前面,将tid转换成了c_long类型。因为传到API中的类型需要是C的长整形,不然会越界。因为在我的环境中,PID是一个较大的值。
解决方案利用的是python内置API,通过ctypes模块调用,在线程中丢出异常,使线程退出。
希望我的分享能给各位python程序猿一些帮助。