【问题标题】:threading.Timer to kill long running task with basic cleanup controlthreading.Timer 用基本的清理控制杀死长时间运行的任务
【发布时间】:2018-05-22 17:20:54
【问题描述】:

我想监控一个进程并在它运行超过 N 秒时自动终止它。

我正在编辑这个问题,以回应它与以下内容重复的建议: Is there any way to kill a Thread in Python?

我认为我的问题略有不同,因为我专注于线程完成后的基本清理(这实际上可能比上述可能的重复更困难,因为每个人似乎都说这是不可能的)。

作为一个简单的测试,我正在尝试以下方法来尝试在 2 秒后终止该进程:

import threading
import sys
import time

def after_timeout():
  print "KILL THE WORLD HERE!"
  # whats the secret sauce here (if any)?
  # sys.exit() and other variants aren't
  # killing the main thread... is it possible?

threading.Timer(2, after_timeout).start()

i = 0
while True:
  print i
  i += 1
  time.sleep(1)

【问题讨论】:

  • 我 99% 确定我很愚蠢,只是在这里遗漏了一些非常基本的东西。但是...我不能保证我的长期运行过程实际上是在迭代,所以我不能保证它会在这样的解决方案中达到“if e.is_set()”。
  • @zvone hrmm...我可能同意。 :-) 现在阅读该问题的答案。
  • @zvone 刚刚发布了我的问题的更新以及我目前提出的批评解决方案 :-)

标签: python timeout


【解决方案1】:

所以...我认为可以通过组合 10 个不同的 SO 帖子以一种我在任何单个 SO 帖子中都没有见过的方式来解决这个问题...请批评并告诉我这是愚蠢还是聪明... ;-)

[因为这个问题至少与其他两个问题密切相关...我已将我提出的解决方案作为独立答案发布在两个相关线程中:12]

import threading
import time
import atexit

def do_work():

  i = 0
  @atexit.register
  def goodbye():
    print ("'CLEANLY' kill sub-thread with value: %s [THREAD: %s]" %
           (i, threading.currentThread().ident))

  while True:
    print i
    i += 1
    time.sleep(1)

t = threading.Thread(target=do_work)
t.daemon = True
t.start()

def after_timeout():
  print "KILL MAIN THREAD: %s" % threading.currentThread().ident
  raise SystemExit

threading.Timer(2, after_timeout).start()

产量:

0
1
KILL MAIN THREAD: 140013208254208
'CLEANLY' kill sub-thread with value: 2 [THREAD: 140013674317568]

我认为这是适用于我的应用程序的秘诀。我的子线程现在在固定的时间后被正确清理,在所述子线程中没有循环标志检查废话......而且我似乎什至在子线程中获得了一点控制,我可以做一些最终状态检查和清理。

【讨论】:

    【解决方案2】:

    当我尝试您的代码时,似乎“秘诀”实际上是 daemon=True 标志而不是引发 SystemExit,并且代码无法按您预期的那样工作。我的意思是,如果你在最后写这样的话:

    print("still continuing")
    time.sleep(5)
    print("by now, the second thread should have already be killed, but it's not...")
    print("exiting, naturally, by closing the main thread..., just now the second thread will also close, being a daemon thread")
    

    这仍然很有用,这意味着你不必杀死你的线程,你可以让你的主程序/线程尽早退出,在等待一些超时之后,但在退出之前,它可以发出超时信号-在磁盘或数据库上以持久方式出错。退出你的主线程是杀死你的其他线程的最有效方法,我假设在这一点上,它对我来说很好,因为我的主程序被设计为只对其逻辑运行一次迭代,然后重新生成通过 systemctl 强大的机制。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多