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

Прерывать/прерывать time.sleep() в python

Мне нужно перерыв с time.sleep() с помощью ctrl c.

While 1:
    time.sleep(60)

В приведенном выше коде, когда элемент управления вводит функцию time.sleep, для завершения работы python требуется 60 секунд для обработки CTRL C

Есть ли элегантный способ сделать это. так что я могу прерывать, даже когда элемент управления находится в режиме time.sleep

изменить

Я тестировал его на устаревшей реализации, которая использует python 2.2 на Windows 2000, которая вызвала все проблемы. Если бы я использовал более высокую версию python, CTRL C прервал бы sleep(). Я быстро взломал вызов sleep (1) внутри цикла for. который временно исправил мою проблему

4b9b3361

Ответ 1

Не уверен, в чем смысл этого кода, но при необходимости используйте более короткий интервал sleep() и поместите вокруг него цикл for:

for i in range(60):
   sleep(1)

Захват исключения KeyboardInterrupt с использованием try..except прямолинейно

Ответ 2

Правильный ответ - использовать python stdlib threading.Event

Конечно, вы можете настроить интервал сна, чтобы вы спали в течение очень коротких периодов, но что, если вы действительно хотите запускать цикл один раз каждые 60 с? Затем вам нужно проделать дополнительную работу, чтобы определить, пора ли бежать или просто спать. Кроме того, вы все еще технически блокируете, но только на короткий промежуток времени. Контраст с threading.Event:

from threading import Event

exit = Event()

def main():
    while not exit.is_set():
      do_my_thing()
      exit.wait(60)

    print("All done!")
    # perform any cleanup here

def quit(signo, _frame):
    print("Interrupted by %d, shutting down" % signo)
    exit.set()

if __name__ == '__main__':

    import signal
    for sig in ('TERM', 'HUP', 'INT'):
        signal.signal(getattr(signal, 'SIG'+sig), quit);

    main()

Когда обработчик сигнала вызывает exit.set(), вызов основного потока wait() будет немедленно прерван.

Теперь вы можете использовать Event чтобы сигнализировать о том, что нужно проделать еще больше работы и т.д. Но в этом случае он выполняет двойную функцию в качестве удобного индикатора, который мы хотим выйти (например, часть while not exit.is_set().)

У вас также есть возможность поставить любой код очистки после в while цикл.

Ответ 3

Исключение KeyboardInterrupt возникает, когда пользователь нажимает клавишу прерывания Ctrl-C. В python это переводится из сигнала SIGINT. Это означает, что вы можете обращаться с ним, но вы хотите использовать сигнальный модуль:

import signal

def handler(signum, frame):
    print "do whatever, like call thread.interrupt_main()"

signal.signal(signal.SIGINT, handler)

while 1:
    time.sleep(forever)

Таким образом, вы можете делать все, что хотите, при получении прерывания клавиатуры.

Ответ 4

Я попробовал свой код с версиями python 2.5, 2.6, 3 под Linux и все исключил исключение KeyboardInterrupt при нажатии CTRL-C.

Возможно, какая-то обработка исключений прерывает прерывание или ваша проблема выглядит так: Почему KeyboardInterrupt не работает в python?

Ответ 5

Самое элегантное решение, безусловно, threading.Event, хотя если вам нужен только быстрый взлом, этот код работает хорошо:

import time

def main():
    print("It’s time !")

if __name__ == "__main__":
    print("press ctrl-c to stop")
    loop_forever = True
    while loop_forever:
        main()
        try:
            time.sleep(60)
        except KeyboardInterrupt:
            loop_forever = False

Ответ 6

Подумал, что я добавлю это.

import time


def sleep(seconds):
    for i in range(seconds):
        try:
            time.sleep(1)
        except KeyboardInterrupt:
            continue


sleep(60)