Python中的限制函数执行

2024-04-19 20:45:05 发布

您现在位置:Python中文网/ 问答频道 /正文

有很多类似的问题和疑问,但我还是找不到可靠的答案。在

所以,我有一个函数,可能会运行太长。函数是私有的,在某种意义上我不能改变它的代码。在

我想把它的执行时间限制在60秒。 我尝试了以下方法:

  1. Python信号。不要在Windows和多线程环境中工作(mod wsgi)。在
  2. 线程。很好的方法,但是线程不能停止,因此它甚至在提升TimeoutException之后仍然存在。在
  3. multiprocessingpython模块。我有腌制的问题,我不知道怎么解决。我想做限时装饰器,在顶层导入所需函数有问题。长时间执行的函数是实例方法,包装它也无助于。。。在

那么,上述问题有没有好的解决方案呢? 如何杀死线程,我开始? 如何使用子流程和避免酸洗问题? subprocess模块是否有任何帮助?在

谢谢。在


Tags: 模块方法函数答案代码modwsgi信号
2条回答

我认为多处理方法是你唯一的选择。你是正确的,线程不能被杀死(很好),信号有跨平台的问题。下面是一个多处理实现:

import multiprocessing
import Queue

def timed_function(return_queue):
    do_other_stuff()
    return_queue.put(True)
    return

def main():

    return_queue = multiprocessing.Manager().Queue()

    proc = multiprocessing.Process(target=timed_function, args=(return_queue,))
    proc.start()

    try:

        # wait for 60 seconds for the function to return a value
        return_queue.get(timeout=60)

    except Queue.Empty:
        # timeout expired
        proc.terminate() # kill the subprocess
        # other cleanup

我知道你说过你有酸洗问题,但这些问题几乎总是可以通过重构来解决的。例如,您说过long函数是一个实例方法。您可以包装这些类型的函数,以便在多处理中使用它们:

^{pr2}$

要在工作线程池中使用该方法,请将此包装器添加到模块的顶层:

def _timed_method_wrapper(TestClass_object, return_queue):
    return TestClass_object(return_queue)

例如,现在您可以在这个类方法上使用apply_async,该类方法来自同一类的另一个方法:

def run_timed_method():
    return_queue = multiprocessing.Manager().Queue()
    pool = multiprocessing.Pool()
    result = pool.apply_async(_timed_method_wrapper, args=(self, return_queue))

我确信这些包装器只有在使用multiprocessing.Pool而不是用multiprocessing.Process对象启动子进程时才是必要的。另外,我敢打赌很多人都会不赞成这种结构,因为你破坏了类提供的漂亮、干净的抽象,并且在类和其他随机包装函数之间建立了依赖关系。你必须决定让你的代码更难看是否值得。在

一个answerIs it possible to kill a process on Windows from within Python?可能有帮助: 您需要终止该子进程或线程: "Terminating a subprocess on windows"

或许TerminateThread也有帮助

相关问题 更多 >