【问题标题】:python interrupt a command if it takes longer than it should [duplicate]如果命令花费的时间超过应有的时间,python会中断命令[重复]
【发布时间】:2013-01-17 02:27:49
【问题描述】:

可能重复:
Timeout on a Python function call
How to timeout function in python, timout less than a second

我在 for 循环中运行一个函数,如下所示:

for element in my_list:
    my_function(element)

由于某种原因,某些元素可能会导致函数处理时间很长(甚至可能是一些我无法真正追踪它来自何处的无限循环)。因此,如果当前元素的处理时间超过 2 秒,我想添加一些循环控制来跳过当前元素。如何做到这一点?

【问题讨论】:

  • 查看timeit 函数。也许它有帮助! docs.python.org/2/library/timeit.html
  • 可以修改my_function吗?如果是这样,你也许可以在那里设置一个救助条件。
  • 当你有一个 bug 时,你应该追踪它并修复它,而不是避免它

标签: python


【解决方案1】:

类似这样的:

import signal
import time

class Timeout(Exception): 
    pass 

def try_one(func,t):
    def timeout_handler(signum, frame):
        raise Timeout()

    old_handler = signal.signal(signal.SIGALRM, timeout_handler) 
    signal.alarm(t) # triger alarm in 3 seconds

    try: 
        t1=time.clock()
        func()
        t2=time.clock()

    except Timeout:
        print('{} timed out after {} seconds'.format(func.__name__,t))
        return None
    finally:
        signal.signal(signal.SIGALRM, old_handler) 

    signal.alarm(0)
    return t2-t1

def troublesome():
    while True:
        pass

try_one(troublesome,2)

函数troublsome 永远不会自行返回。如果你使用try_one(troublesome,2),它会在 2 秒后成功超时。

【讨论】:

    【解决方案2】:

    我不鼓励最明显的答案 - 使用 signal.alarm() 和异步引发异常以跳出任务执行的警报信号处理程序。理论上它应该工作得很好,但实际上 cPython 解释器代码并不能保证处理程序在您想要的时间范围内执行。信号处理可能会延迟 x 条字节码指令,因此在显式取消警报后(在 try 块的上下文之外)仍可能引发异常。

    我们经常遇到的一个问题是警报处理程序的异常会在可超时代码完成后引发

    由于没有太多可用的线程控制方式,我依靠进程控制来处理必须超时的任务。基本上,要点是将任务交给子进程并在任务花费太长时间时终止子进程。 multiprocessing.pool 并没有那么复杂 - 所以我有一个家庭滚动的池来进行这种级别的控制。

    【讨论】:

      猜你喜欢
      • 2023-01-30
      • 2021-08-09
      • 2021-04-29
      • 2012-08-19
      • 1970-01-01
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 2022-01-20
      相关资源
      最近更新 更多