关于python:如果函数花费的时间太长,是否跳过循环?

Skip loop if a function is taking too long?

我有一个python代码,花费的时间太长,如果这个函数花费的时间超过几秒钟,我想停止并跳过它的执行。

例如:

我想要时间的功能是

1
batch_xs, batch_ys = train_loadbatch_from_lists(batch_size)

在某些情况下,此函数调用花费的时间太长,希望取消它。

我在找这样的东西

1
2
if time for batch_xs, batch_ys = train_loadbatch_from_lists(batch_size) > 20 seconds:
    then skip

关于这篇文章。

我想知道如果发生超时,如何重新调用函数。

例如:

1
2
3
@timeout(15)
def abcd(hello):
#some def

如果函数与计时器交叉,我想再次调用它。


当您在同一线程中调用一个函数时,它通常不会返回,直到完成为止。您调用的函数必须首先设计为可中断。实现这一点的方法有很多种,有不同程度的复杂性和通用性。

可能最简单的方法是将时间限制传递给函数,并以小块的形式处理工作。在处理每个块之后,检查经过的时间是否超过超时值,如果超过超时值,则提前退出。

下面的示例说明了这一想法,其中每个块所花费的时间是随机的,有时会完成,有时会超时:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import time
import random
import datetime

class TimeoutException(Exception):
    def __init__(self, *args, **kwargs):
        Exception.__init__(self, *args, **kwargs)

def busy_work():

    # Pretend to do something useful
    time.sleep(random.uniform(0.3, 0.6))

def train_loadbatch_from_lists(batch_size, timeout_sec):

    time_start = datetime.datetime.now()
    batch_xs = []
    batch_ys = []

    for i in range(0, batch_size+1):
        busy_work()
        batch_xs.append(i)
        batch_ys.append(i)

        time_elapsed = datetime.datetime.now() - time_start
        print 'Elapsed:', time_elapsed
        if time_elapsed > timeout_sec:
            raise TimeoutException()

    return batch_xs, batch_ys

def main():

    timeout_sec = datetime.timedelta(seconds=5)
    batch_size = 10
    try:
        print 'Processing batch'
        batch_xs, batch_ys = train_loadbatch_from_lists(batch_size, timeout_sec)
        print 'Completed successfully'
        print batch_xs, batch_ys
    except TimeoutException, e:
        print 'Timeout after processing N records'

if __name__ == '__main__':
    main()

实现这一点的另一种方法是在单独的线程中运行worker函数,并使用Event允许调用者向worker函数发出提前终止的信号。

有些帖子(如上面链接的帖子)建议使用信号,但不幸的是,信号会导致额外的并发症,因此不建议使用。