Как вернуться из функции, если она застряла на 90 секунд?

Возможный дубликат:
Тайм-аут при вызове функции Python

Я хочу реализовать это, когда функция заняла более 90 секунд, она должна немедленно вернуться к таймауту. Есть ли способ достичь этого?

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

abc('some string to match')

Edited

Загрузите этот файл теста. Я создал класс потока и создаю исключение в потоке, если возникла ошибка тайм-аута. Но поток все еще жив, потому что он печатает i am still alive :) даже после исключения. Почему исключение не заставляет поток останавливаться?

Ответ 1

Я редактировал свой пост, чтобы использовать jcollado idea, который проще.

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

Обратите внимание, что вы получаете сообщение "Timed out" за 5 секунд, даже если abc('some string',20) заняло около 20 секунд.

Ответ 2

Один из способов справиться с этим - поставить эту задачу в поток и использовать сторожевой таймер, чтобы убить ее через 90 секунд.

Здесь рецепт в ActiveState.

Изменить: Очевидно, что рецепт сам по себе не является полным решением. У вас будет либо сторожевой поток, который проверял каждые x секунд, если рабочий поток был выполнен, либо вы попали бы в фреймворк событий, например Майкл Форд простая инфраструктура событий.