Python, тайм-аут попытки, кроме оператора после X числа секунд? - PullRequest
4 голосов
/ 28 сентября 2010

Я искал по этому вопросу, но, похоже, не могу найти точного ответа (большинство попадают в более сложные вещи, такие как многопоточность и т. Д.), Я просто хочу сделать что-то вроде оператора Try, Except, где, если процесс неНе завершите в течение X секунд, он выдаст исключение.

РЕДАКТИРОВАТЬ: Причина этого в том, что я использую программное обеспечение для тестирования веб-сайта (селен) с конфигурацией, которая иногда вызывает его зависание.Это не выдает ошибку, не делает тайм-аут или делает что-либо, поэтому у меня нет возможности ее перехватить.Мне интересно, как лучше всего определить, что это произошло, чтобы я мог двигаться дальше в своем приложении, поэтому я подумал, могу ли я сделать что-то вроде: «если это не закончилось к X секундам ... двигаться дальше».

Ответы [ 3 ]

2 голосов
/ 28 сентября 2010

Вы не можете сделать это без какой-либо многопоточности или многопроцессорности, даже если это скрыто под некоторыми уровнями абстракции, если только этот «процесс», который вы запускаете, не предназначен специально для асинхронности и однократного вызова известной функции через некоторое время.

Если вы опишите, что на самом деле представляет собой этот процесс, вам будет легче найти реальные решения. Я не думаю, что вы цените мощь Python, когда речь идет о реализациях, которые являются лаконичными, будучи завершенными. Для реализации может потребоваться всего несколько строк кода, даже если используется многопоточность / многопроцессорность.

1 голос
/ 28 сентября 2010

Ответ (и вопрос) не относится к выражению try / исключением. Если вы хотите иметь бесконечный цикл, который не является бесконечным (но останавливается через некоторое время), он, вероятно, не должен быть бесконечным. Например, измените его на использование:

while time <= some_value:

Или добавьте дополнительную проверку к телу цикла, разрывая его, когда вы хотите, чтобы он остановился:

while True:
    ...
    if time > some_value:
        break

Если это невозможно (например, потому что вы вообще не контролируете цикл), все становится значительно сложнее. Во многих системах вы можете использовать signal.alarm для доставки сигнала через некоторое время, а затем иметь обработчик сигнала для signal.SIGALRM, который вызывает ваше исключение TimeoutError. Это может или не может работать в зависимости от того, что фактически делает бесконечный цикл; если он блокирует сигналы, или перехватывает и игнорирует исключения, или каким-либо другим образом мешает обработчику сигналов, это не сработает. Другой возможностью было бы сделать цикл не в текущем процессе, а в отдельном; затем вы можете прекратить отдельный процесс по своему усмотрению. Однако будет нелегко что-либо сделать, кроме как прекратить его, поэтому очистка или восстановление частичной работы очень трудны. (Потоки вообще не будут работать, потому что нет способа прервать отдельный поток, выполняя бесконечный цикл.)

0 голосов
/ 07 ноября 2017

Общее решение, если вы используете UNIX:

import time as time
import signal

#Close session
def handler(signum, frame):
    print 1
    raise Exception('Action took too much time')


signal.signal(signal.SIGALRM, handler)
signal.alarm(3) #Set the parameter to the amount of seconds you want to wait

try:
    #RUN CODE HERE

    for i in range(0,5):
        time.sleep(1)
except:
    print 2

signal.alarm(10) #Resets the alarm to 10 new seconds
signal.alarm(0) #Disables the alarm 
...