如果循环内部调用的函数执行时间太长,你怎么能跳过python中的循环迭代?

How can you skip a loop iteration in python if a function called inside the loop takes too long to execute?

我想循环一组文件,并对每个文件执行"runthingy()"中指定的操作。但是,由于此操作在某些文件上卡住,导致整个程序停止,因此如果完成此特定文件的时间超过120秒,我希望跳过它。我使用的是windows,这就是signal.sigalarm不可用的原因,所以我使用stopit库(https://pypi.org/project/stopit/)。以下示例代码将在3秒后中止while循环和打印超时:

1
2
3
4
5
6
7
with stopit.ThreadingTimeout(3) as to_ctx_mrg:
    while(True):
        continue


if to_ctx_mrg.state == to_ctx_mrg.TIMED_OUT:
        print("Time out")

但是,如果runthingy()函数被卡住/需要很长时间才能完成,则在此上下文中使用它将永远不会打印超时:

1
2
3
4
5
6
for filename in os.listdir(os.getcwd()+"\\files\"):
    with stopit.ThreadingTimeout(120) as to_ctx_mrg:
        runthingy(filename)
    if to_ctx_mrg.state == to_ctx_mrg.TIMED_OUT:
        print("
Time out")
        continue

我对您正在使用的库没有经验,但它说它会在超时线程中引发异步异常。

问题是为什么你的函数会被"卡住"?python解释器只会检测到在该线程中解释python指令时引发了异常。如果函数坚持的原因是它发出了一个尚未返回的C调用,那么其他的python线程可能仍然可以运行,但它们不能中断远程线程。

您需要更仔细地研究一下为什么"runthingy()"块。它是从套接字读取数据,还是等待文件锁定?如果该块的调用有一个可选的超时,那么请确保将超时参数设置得相当低:即使代码只是在超时后重试调用,它至少给了Python解释器一个进入并中止进程的机会。

更好的是,如果您能找出函数为什么会卡住,那么您就可以修复底层问题,而不是应用蛮力超时。