在给定的时间后杀死python函数

时间:2016-12-01 16:21:49

标签: python multithreading timer signal-processing

在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')

这两种方法的范围,安全性和可用性有哪些优缺点?还有更好的方法吗?

1 个答案:

答案 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,并且您的线程最终会注意到并退出。

我可能只是去进行多处理和加入。

哈努哈利