Подтвердить что ты не робот

Как бы я остановил цикл while через n времени?

как бы я остановил цикл while через 5 минут, если он не достиг того, чего я хочу достичь.

while true:
    test = 0
    if test == 5:
        break
    test = test - 1

Этот код бросает меня в бесконечный цикл.

4b9b3361

Ответ 1

Попробуйте следующее:

import time
timeout = time.time() + 60*5   # 5 minutes from now
while True:
    test = 0
    if test == 5 or time.time() > timeout:
        break
    test = test - 1

Вы также можете добавить короткий сон здесь, чтобы этот цикл не зависал CPU (например, time.sleep(1) в начале или конце тела цикла).

Ответ 2

Попробуйте этот модуль: http://pypi.python.org/pypi/interruptingcow/

from interruptingcow import timeout
try:
    with timeout(60*5, exception=RuntimeError):
        while True:
            test = 0
            if test == 5:
                break
            test = test - 1
except RuntimeError:
    pass

Привет

Ответ 3

В этом случае вам не нужно использовать цикл while True:. Существует гораздо более простой способ непосредственного использования времени:

import time

# timeout variable can be omitted, if you use specific value in the while condition
timeout = 300   # [seconds]

timeout_start = time.time()

while time.time() < timeout_start + timeout:
    test = 0
    if test == 5:
        break
    test -= 1

Ответ 4

import time

abort_after = 5 * 60
start = time.time()

while True:
  delta = time.time() - start
  if delta >= abort_after:
    break

Ответ 5

Ответ Петр Крампл - лучший, на мой взгляд, но нужно еще многое сказать о природе циклов и о том, как оптимизировать использование системы. Начинающие, которые происходят в этом потоке, могут еще больше смущаться логическими и алгоритмическими ошибками в вопросе и существующих ответах.

Во-первых, давайте посмотрим, что делает ваш код, когда вы его написали:

while True:
    test = 0
    if test == 5:
        break
    test = test - 1

Если вы говорите while True в контексте цикла, обычно ваше намерение состоит в том, чтобы оставаться в цикле навсегда. Если это не ваше намерение, вы должны рассмотреть другие варианты структуры цикла. Петр Крампл показал вам совершенно разумный способ справиться с этим, что гораздо более ясно для кого-то, кто может читать ваш код. Кроме того, вам будет понятнее несколько месяцев спустя, если вам нужно пересмотреть свой код, чтобы добавить или исправить что-то. Хорошо написанный код является частью вашей документации. Обычно есть несколько способов сделать что-то, но это не делает все способы одинаково действительными во всех контекстах. while True является хорошим примером этого особенно в этом контексте.

Далее мы рассмотрим алгоритмическую ошибку в вашем исходном коде. Самое первое, что вы делаете в цикле, - назначить 0 на test. Следующее, что вы делаете, это проверить, является ли значение test равным 5, что никогда не будет иметь место, если у вас есть несколько потоков, изменяющих одно и то же место в памяти. Threading не подходит для обсуждения, но стоит отметить, что код может технически работать, но даже с несколькими потоками много будет отсутствовать, например. семафоры. Во всяком случае, вы будете сидеть в этом цикле навсегда независимо от того, что дозорный генератор вызывает бесконечный цикл.

Оператор test = test - 1 бесполезен, независимо от того, что он делает, потому что переменная reset в начале следующей итерации цикла. Даже если вы изменили его на test = 5, цикл все равно будет бесконечным, так как значение будет reset каждый раз. Если вы переместите оператор инициализации за пределы цикла, у него, по крайней мере, будет шанс выйти. То, что вы, возможно, предназначили, было примерно таким:

test = 0
while True:
    test = test - 1
    if test == 5:
        break

Порядок операторов в цикле зависит от логики вашей программы. Это будет работать в любом порядке, хотя это и главное.

Следующая проблема - потенциальная и вероятная логическая ошибка, начинающаяся с 0, непрерывное вычитание 1, а затем сравнение с положительным числом. Да, бывают случаи, когда это действительно может быть тем, что вы намереваетесь делать, пока вы понимаете последствия, но это скорее всего не то, что вы намеревались. Более новые версии python не обернутся, когда вы достигнете "нижней" диапазона целого числа, такого как C и других языков. Это позволит вам продолжать вычитать 1, пока вы не заполнили доступную память в вашей системе или, по крайней мере, то, что было выделено для вашего процесса. Посмотрите на следующий script и результаты:

test = 0

while True:
    test  -= 1

    if test % 100 == 0:
        print "Test = %d" % test

    if test == 5:
        print "Test = 5"
        break

который производит это:

Test = -100
Test = -200
Test = -300
Test = -400
...
Test = -21559000
Test = -21559100
Test = -21559200
Test = -21559300
...

Значение test никогда не будет равно 5, поэтому этот цикл никогда не выйдет.

Чтобы добавить к Petr Krampl ответ, вот версия, которая, вероятно, ближе к тому, что вы на самом деле планировали в дополнение к выходу из цикла через определенный период времени:

import time

test = 0
timeout = 300   # [seconds]

timeout_start = time.time()

while time.time() < timeout_start + timeout:
    if test == 5:
        break
    test -= 1

Он по-прежнему не будет разбиваться на основе значения test, но это вполне допустимый цикл с разумным начальным условием. Дальнейшая проверка границ может помочь вам избежать выполнения очень длинного цикла без каких-либо причин, например. проверьте, не превышает ли значение теста значение 5 после записи цикла, которое немедленно нарушит цикл.


Следует упомянуть еще одно, что никакой другой ответ не рассматривался. Иногда, когда вы петли, как это, вы можете не захотеть потреблять процессор за все выделенное время. Например, скажите, что вы проверяете значение того, что меняется каждую секунду. Если вы не вводите какую-либо задержку, вы будете использовать каждый доступный цикл ЦП, выделенный для вашего процесса. Это прекрасно, если это необходимо, но хороший дизайн позволит много программ работать параллельно в вашей системе, не перегружая имеющиеся ресурсы. Простой оператор сна освободит подавляющее большинство циклов процессора, выделенных вашему процессу, чтобы другие программы могли работать.

Следующий пример не очень полезен, но он демонстрирует концепцию. Скажем, вы хотите печатать что-то каждую секунду. Один из способов сделать это будет следующим:

import time

tCurrent = time.time()

while True:
    if time.time() >= tCurrent + 1:
        print "Time = %d" % time.time()
        tCurrent = time.time()

Выход будет следующим:

Time = 1498226796
Time = 1498226797
Time = 1498226798
Time = 1498226799

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

введите описание изображения здесь

Это огромный объем использования ЦП для работы в основном без работы. Этот код намного приятнее для остальной части системы:

import time

tCurrent = time.time()

while True:
    time.sleep(0.25) # sleep for 250 milliseconds
    if time.time() >= tCurrent + 1:
        print "Time = %d" % time.time()
        tCurrent = time.time()

Вывод одинаков:

Time = 1498226796
Time = 1498226797
Time = 1498226798
Time = 1498226799

и использование ЦП - это путь, путь ниже:

введите описание изображения здесь

Ответ 6

Я хочу поделиться тем, что я использую:

import time
# provide a waiting-time list:
lst = [1,2,7,4,5,6,4,3]
# set the timeout limit
timeLimit = 4

for i in lst:
    timeCheck = time.time()
    while True:
        time.sleep(i)
        if time.time() <= timeCheck + timeLimit:
            print ([i,'looks ok'])
            break
        else:
            print ([i,'too long'])
            break

Затем вы получите:

[1, 'looks ok']
[2, 'looks ok']
[7, 'too long']
[4, 'looks ok']
[5, 'too long']
[6, 'too long']
[4, 'looks ok']
[3, 'looks ok']