我有一些常规运行的代码,并且时不时(比如一个月一次)程序似乎挂在某处,我不知道在哪里。
我以为我会实现[已经证明并不完全]一个“快速解决方案”来检查程序运行的时间。我决定使用多线程来调用函数,然后在它运行时检查时间。
例如:
import datetime
import threading
def myfunc():
#Code goes here
t=threading.Thread(target=myfunc)
t.start()
d1=datetime.datetime.utcnow()
while threading.active_count()>1:
if (datetime.datetime.utcnow()-d1).total_seconds()>60:
print 'Exiting!'
raise SystemExit(0)
但是,这并没有关闭其他线程(myfunc)。
杀死其他线程的最佳方法是什么?
答案 0 :(得分:3)
文档可以更加清楚。提升SystemExit
告诉解释器退出,但“正常”退出处理仍然完成。正常退出处理的一部分是.join()
- 所有活动的非守护程序线程。但是你的流氓线程永远不会结束,所以退出处理会永远等待加入它。
正如@roippi所说,你可以做到
t.daemon = True
开始之前。正常退出处理不等待守护程序线程。当主进程退出时,你的操作系统应该杀死它们。
另一种选择:
import os
os._exit(13) # whatever exit code you want goes there
“立即”停止翻译,并跳过所有正常退出处理。
选择你的毒药; - )
答案 1 :(得分:1)
没有办法杀死一个线程。您必须从目标中杀死目标。最好的方法是使用钩子和queue。它就是这样的。
import Threading
from Queue import Queue
# add a kill_hook arg to your function, kill_hook
# is a queue used to pass messages to the main thread
def myfunc(*args, **kwargs, kill_hook=None):
#Code goes here
# put this somewhere which is periodically checked.
# an ideal place to check the hook is when logging
try:
if q.get_nowait(): # or use q.get(True, 5) to wait a longer
print 'Exiting!'
raise SystemExit(0)
except Queue.empty:
pass
q = Queue() # the queue used to pass the kill call
t=threading.Thread(target=myfunc, args = q)
t.start()
d1=datetime.datetime.utcnow()
while threading.active_count()>1:
if (datetime.datetime.utcnow()-d1).total_seconds()>60:
# if your kill criteria are met, put something in the queue
q.put(1)
我最初在网上找到了这个答案,可能是this。希望这有帮助!
另一种解决方案是使用单独的Python实例,并使用psutils监视其他Python线程,从系统级别将其杀死。
哇,我也喜欢守护进程和秘密的os._exit解决方案!