在Python中给定时间后杀死一个函数(仍在运行)的最佳方法是什么?这是迄今为止我发现的两种方法:
说这是我们的基本功能:
import time
def foo():
a_long_time = 10000000
time.sleep(a_long_time)
TIMEOUT = 5 # seconds
1。多处理方法
import multiprocessing
if __name__ == '__main__':
p = multiprocessing.Process(target=foo, name="Foo")
p.start()
p.join(TIMEOUT)
if p.is_alive()
print('function terminated')
p.terminate()
p.join()
2。信号方法
import signal
class TimeoutException(Exception):
pass
def timeout_handler(signum, frame):
raise TimeoutException
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(TIMEOUT)
try:
foo()
except TimeoutException:
print('function terminated')
这两种方法的范围,安全性和可用性有哪些优缺点?还有更好的方法吗?
答案 0 :(得分:1)
嗯,一如既往,这取决于。
您可能已经验证过,这两种方法都有效。我会说这取决于你的应用程序和正确的实现(你的信令方法有点不对......)
如果正确实施,这两种方法都可视为“安全”。这取决于foo函数之外的主程序是否需要执行某些操作,或者只是等待foo完成或超时。信令方法不允许任何并行处理,因为您的主程序将在foo()中,直到它完成或超时。但是你需要消除信号。如果你的foo在一秒钟内完成,你的主程序将离开try / except结构,四秒钟之后... kaboom ...异常被提出并且可能未被捕获。不好。
try:
foo()
signal.alarm(0)
except TimeoutException:
print ("function terminated")
解决了这个问题。
我个人更喜欢多处理方法。它更简单,并且不需要信号和异常处理,如果您的程序执行不是您发出信号时的预期,理论上可能会出错。如果您的程序可以在join()中等待,那么您就完成了。但是,如果您想在等待时在主进程中执行某些操作,则可以输入循环,在变量中跟踪时间,检查是否超时,如果是,则终止进程。如果进程仍在运行,你只需使用一个微小超时的连接来“窥视”。
另一种方法,取决于你的foo(),是使用带有类或全局变量的线程。如果你的foo继续处理命令而不是等待很长时间才能完成一个命令,你可以在那里添加一个if子句:
def foo():
global please_exit_now
while True:
do_stuff
do_more_stuff
if foo_is_ready:
break
if please_exit_now is True:
please_exit_now = False
return
finalise_foo
return
如果do_stuff和do_more_stuff在合理的时间内完成,那么您可以在主程序中处理事物并将全局please_exit_now设置为True,并且您的线程最终会注意到并退出。
我可能只是去进行多处理和加入。
哈努哈利