【问题标题】:Programmatically exiting python script while multithreading多线程时以编程方式退出python脚本
【发布时间】:2013-09-27 21:17:55
【问题描述】:

我有一些定期运行的代码,并且时不时地(比如每月一次)程序似乎挂在某个地方,我不确定在哪里。

我想我会实现 [结果不完全是] 检查程序运行了多长时间的“快速修复”。我决定使用多线程来调用函数,然后在它运行时,检查时间。

例如:

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)。

杀死另一个线程的最佳方法是什么?

【问题讨论】:

标签: python multithreading


【解决方案1】:

文档可能会更清楚地说明这一点。提高SystemExit 告诉解释器退出,但“正常”退出处理仍然完成。正常退出处理的一部分是.join()-ing 所有活动的非守护线程。但是你的流氓线程永远不会结束,所以退出处理永远等待加入它。

正如@roippi 所说,你可以做到

t.daemon = True

在开始之前。正常退出处理等待守护线程。当主进程退出时,您的操作系统应该杀死它们。

另一种选择:

import os
os._exit(13)  # whatever exit code you want goes there

这会“立即”停止解释器,并跳过所有正常退出处理。

选择你的毒药 ;-)

【讨论】:

  • 请注意这会破坏 'atexit' 回调
【解决方案2】:

没有办法杀死线程。你必须从目标内部杀死目标。最好的方法是使用钩子和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 解决方案!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 2016-01-02
    • 2014-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多