如何在被卡住90秒后从函数返回?

11 投票
2 回答
2365 浏览
提问于 2025-04-17 07:14

可能重复的问题:
Python函数调用超时

我想实现一个功能,就是当某个函数执行超过90秒时,它应该立即返回,表示超时。有没有办法做到这一点呢?

def abc(string):
    import re
    if re.match('some_pattern', string):
        return True
    else:
        return False

abc('some string to match')

编辑过

请下载这个测试文件。我创建了一个线程类,并在超时发生时在线程中抛出一个异常。但是线程仍然在运行,因为即使在抛出异常后,它还是会打印我还活着 :)。为什么抛出异常并没有让线程停止呢?

2 个回答

0

处理这个问题的一种方法是把这个任务放到一个线程里,然后用一个监视器在90秒后把它结束掉。

这里有一个ActiveState的示例

补充说明:显然,这个示例本身并不是完整的解决方案。你可以有一个监视线程,每隔一段时间检查一下工作线程是否完成,或者你可以使用像Michael Ford的简单事件框架这样的事件框架。

6

我已经修改了我的帖子,采用了jcollado的想法,这个方法更简单。

multiprocessing.Process.join这个方法有一个超时参数,你可以这样使用:

import multiprocessing as mp
import time
import logging  
import re

logger = logging.getLogger(__name__)

def abc(string, result, wait = 0):
    time.sleep(wait)
    result.put(bool(re.match('some_pattern', string)))

if __name__ == '__main__':
    logging.basicConfig(level = logging.DEBUG,
                        format = '%(asctime)s:  %(message)s',
                        datefmt = '%H:%M:%S', )
    result = mp.Queue()
    proc = mp.Process(target = abc, args = ('some_pattern to match', result))
    proc.start()
    proc.join(timeout = 5)
    if proc.is_alive():
        proc.terminate()
    else:
        logger.info(result.get())

    proc = mp.Process(target = abc, args = ('some string to match', result, 20))
    proc.start()
    proc.join(timeout = 5)
    if proc.is_alive():
        logger.info('Timed out')
        proc.terminate()
    else:
        logger.info(result.get())

这样会得到

12:07:59:  True
12:08:04:  Timed out

注意,即使abc('some string',20)大约需要20秒才能完成,你在5秒后就会收到“超时”的消息。

撰写回答