线程.计时器,用于终止具有基本清理控制的长时间运行的任务



我想监视一个进程,如果它运行超过 N 秒,则自动终止它。

我正在编辑这个问题,以回应它是以下重复的建议: 有没有办法杀死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)

所以...我认为可能已经通过组合 10 个不同的 SO 帖子来解决这个问题,这是我在任何单个 SO 帖子中都没有看到的......请批评并告诉我这是愚蠢还是聪明... ;-(

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

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]

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

当我尝试您的代码时,似乎"秘密调味料"实际上是 daemon=True 标志而不是 raise 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 强机制重生。

相关内容

最新更新