大多数超时上下文解决方案都使用信号。但是信号会被覆盖,只有最后一个信号处理程序保留下来。结果是,如果代码已经在超时上下文中(可能是由您,另一个开发人员,库,框架,知道吗?)启动的,则无法使用超时上下文。
因此,基本上我过度简化的用例是这样:
with Timeout(1): #A
with Timeout(100): #B
sleep(10) #C
print('Fail')
此代码不应打印“失败”。但是到目前为止,我所见过的Timeout()的每种实现都具有相同的作用:
前面的示例似乎有点愚蠢,但实际用例更像是:
with Timeout(30):
for a in list:
with Timeout(10):
heavy_computing(a)
我不知道“列表”的长度,我不希望列表中的每个元素花费超过10s,总计不超过30s。
所以我的问题是:不使用信号并且支持在上下文中嵌入上下文的Timeout()上下文的最佳实现是什么?
编辑:
Edit2:
好,关于我如何考虑超时的一些澄清。对我来说,超时是一种非侵入性的解决方案,如果黑盒操作花费的时间太长,它会返回部分结果(或根本没有结果)。结果必须快速返回,但可能不完整。
def function(argument):
results = []
with Timeout(50):
for a in arguments:
with Timeout(20):
results.append(black_box(a))
return results
如果函数花费的时间超过50s,则中止执行并返回不完整的结果。而且,如果black_box花费的时间超过10秒,则会跳过该操作以继续下一个结果。
示例: 参数= [a,b,c,d] black_box(a)需要25秒并返回w black_box(b)需要20秒并返回x black_box(c)需要5s并返回y black_box(d)需要10s并返回z 结果= [x,y]
说明: 一个花了20多秒并被跳过 b多花了20秒(共40秒)并成功计算 c多花了5秒(共45秒),仍然不到50秒 d由于50超时而中止了
黑盒功能不知道它是从超时上下文中调用的,并且不包含特定于超时的代码。
该代码为例,可能有所不同。也许我们需要尝试一下..除了捕获超时错误等。但是无法修改black_box。