在给定的时间后杀死函数? [英] Kill function after a given amount of time?

查看:52
本文介绍了在给定的时间后杀死函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Python 中在给定时间后终止函数(仍在运行)的最佳方法是什么?这是我目前发现的两种方法:

What's the best way to kill a function (that is still running) after a given amount of time in Python? These are two approaches I have found so far:

说这是我们的基本函数:

Say this is our base function:

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

这两种方法在范围、安全性和可用性方面的优缺点是什么?有没有更好的方法?

What are the advantages and disadvantages in terms of scope, safety and usability of these two methods? Are there any better approaches?

推荐答案

嗯,一如既往,视情况而定.

Well, as always, it depends.

您可能已经验证过,这两种方法都有效.我会说这取决于你的应用程序和正确的实现(你的信号方法有点错误......)

As you probably have already verified, both these methods work. I would say it depends on your application and correct implementation (your signalling method is a bit wrong...)

如果正确实施,这两种方法都可以被认为是安全的".这取决于 foo 函数之外的主程序是否需要做某事,或者它是否可以坐等 foo 完成或超时.信号方法不允许任何并行处理,因为您的主程序将在 foo() 中,直到它完成或超时.但是你需要然后解除信号.如果你的 foo 在一秒钟内完成,你的主程序离开 try/except 结构,四秒钟后...... kaboom......引发异常并且可能未捕获.不好.

Both methods can be considered "safe" if implemented correctly. It depends if your main program outside the foo function needs to do something, or can it just sit and wait for foo to either complete or timeout. The signalling method does not allow any parallel processing, as your main program will be in foo() until it either completes or times out. BUT you need then to defuse the signal. If your foo completes in one second, your main program leaves the try/except structure, and four seconds later ... kaboom ... an exception is raised and probably uncaught. Not good.

try:
    foo()
    signal.alarm(0)
except TimeoutException:
    print ("function terminated")

解决问题.

我个人更喜欢多处理方法.它更简单,不需要信号和异常处理,如果您的程序执行不在您期望的位置,则理论上可能会出错.如果您的程序可以在 join() 中等待,那么您就完成了.但是,如果您想在等待时在主进程中执行某些操作,您可以进入一个循环,跟踪变量中的时间,检查是否超时,如果超时,则终止该进程.如果进程仍在运行,您只需使用带有微小超时的 join 来查看".

I would personally prefer the multiprocessing approach. It is simpler and does not require signals and exception handling that in theory can go wrong if your program execution is not where you expect it to be when a signal is raised. If it is ok for your program to wait in join(), then you are done. However, if you want to do something in the main process while you wait, you can enter a loop, track time in a variable, check if over timeout and if so, terminate the process. You would just use join with a tiny timeout to "peek" if the process is still running.

另一种方法,取决于您的 foo(),是使用带有类或全局变量的线程.如果您的 foo 继续处理命令而不是等待很长时间才能完成,您可以在那里添加一个 if 子句:

Another method, depending on your foo(), is to use threads with a class or a global variable. If your foo keeps processing commands instead of possibly waiting for a long time for a command to finish, you can add an if clause there:

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,你的线程最终会注意到并退出.

If do_stuff and do_more_stuff complete in a reasonable amount of time, you could then process things in your main program and just set global please_exit_now as True, and your thread would eventually notice that and exit.

不过,我可能只是为了您的多处理和加入.

I would probably just go for your multiprocessing and join, though.

汉努

这篇关于在给定的时间后杀死函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆