所以这个问题是对之前发布的解决方案的跟进。基本上它处理以编程方式终止线程:http://sebulba.wikispaces.com/recipe+thread2
然而它不起作用......我想知道是否有人可以解释如何终止阻塞的线程?我唯一的猜测是我没有提供正确的线程ID,但我做了一些测试,我很确定我可以使用iden
如果是线程ID,我该如何获取正确的线程ID?
测试代码:
class BlockingTestThread(Thread):
def __init__(self):
self._running_flag = False
Thread.__init__(self, target=self.test_method)
def test_method(self):
try:
while(not self.stopped()):
self._running_flag = True
time.sleep(100)
finally:
self._running_flag = False
def _async_raise(tid, exctype):
'''Raises an exception in the threads with id tid'''
if not inspect.isclass(exctype):
raise TypeError("Only types can be raised (not instances)")
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exctype))
time.sleep(0.1)
if __name__ == "__main__":
thread = BlockingTestThread()
thread.start()
_async_raise(thread.ident, SystemExit)
print "Joining thread"
thread.join()
print "Done Joining thread"
#will never get here!
答案 0 :(得分:4)
这是一个更好的方法,在事件上使用“wait”命令,假设你想使用sleep。
class BlockingTestThread(Thread):
def __init__(self):
self._running_flag = False
self.stop = threading.Event()
Thread.__init__(self, target=self.test_method)
def test_method(self):
try:
while(not self.stop.wait(1)):
self._running_flag = True
print 'Start wait'
self.stop.wait(100)
print 'Done waiting'
finally:
self._running_flag = False
def terminate(self):
self.stop.set()
if __name__ == "__main__":
thread = BlockingTestThread()
thread.start()
time.sleep(2)
print 'Time sleep 2'
thread.terminate()
print "Joining thread"
thread.join()
print "Done Joining thread"
显然你需要将阻塞线程包装在使用上述模式的东西中,但是如果你不能另一个选择是让你的进程抛出异常,在我们的例子中我们基本上会杀死底层连接,这会导致异常,如果设置了停止标志,则发生异常时,我们会忽略它。
答案 1 :(得分:0)
你是对的,从docs,ident变量没有映射到线程id,它只是一个参考 -
<强> thread.get_ident()强>
返回当前线程的'线程标识符'。这是一个非零整数。它的价值没有直接意义;它旨在作为一种神奇的饼干用于例如索引特定于线程的数据的字典。当线程退出并创建另一个线程时,线程标识符可以被回收。
请参阅http://bytes.com/topic/python/answers/45247-terminating-thread-parent re:killling,不确定它是否正是您正在寻找的。 p>