Python, как мне вручную завершить бесконечный цикл while, который собирает данные, не завершая код и не используя KeyboardInterrupt? - PullRequest
4 голосов
/ 14 июня 2019

В моем коде есть цикл «while True:», который должен работать в течение различного времени при сборе текущих данных (3-5 часов).Поскольку время не определено, мне нужно вручную завершить цикл while без завершения сценария, чтобы он мог перейти к следующему тексту кода в сценарии.

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

ТакжеЯ не хочу использовать прерывание клавиатуры, были проблемы с ним.Есть ли другие решения?Все, что я видел, - это попытка / исключение с «клавиатурным прерыванием»

def datacollect()
def datacypher()

while True:
    #Insert code that collects data here
    datacollect()

#end the while loop and continue on
#this is where i need help

datacypher()
print('Yay it worked, thanks for the help')

Я ожидаю завершить цикл вручную, а затем перейти к коду, который воздействует на собранные данные.

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

Ответы [ 3 ]

4 голосов
/ 14 июня 2019

Как насчет добавления ключевого слушателя во второй поток?После того, как вы нажмете Enter , вы вручную перейдете к следующему этапу сценария с помощью общего bool.Второй поток не должен замедлять процесс, поскольку он блокируется на input().

from threading import Thread
from time import sleep

done = False

def listen_for_enter_key_press():
    global done
    input()
    done = True

listener = Thread(target=listen_for_enter_key_press)
listener.start()

while not done:
    print('working..')
    sleep(1)

listener.join()

print('Yay it worked, thanks for the help')
3 голосов
/ 14 июня 2019

Одним из способов прерывания цикла является использование сигналов.

import signal

def handler(signum, stackframe):
    global DONE
    DONE = True

signal.signal(signal.SIGUSR1, handler)

DONE = False
while not DONE:
    datacollect()

datacypher()

Цикл будет продолжаться до тех пор, пока ваша программа не получит сигнал USR1 (отправленный, например, с оболочки kill -s USR1 <pid>, где <pid> - идентификатор процесса вашей программы), и в этот момент DONE будет True в следующий раз ваш цикл проверяет свое значение.

Это можно адаптировать для прерываний клавиатуры, просто установив handler в качестве обработчика для signal.SIGINT вместо signal.SIGUSR1, поскольку обработчик сигнала по умолчанию - это то, что в первую очередь вызывает исключение KeyboardInterrupt.

0 голосов
/ 14 июня 2019

Один из вариантов, вы можете искать существование файла, например:

import os.path

fname = '/tmp/stop_loop'

def datacollect()
def datacypher()

while not os.path.isfile(fname):
    #Insert code that collects data here
    datacollect()

#end the while loop and continue on
#this is where i need help

datacypher()
print('Yay it worked, thanks for the help')

Если этот файл не существует, он будет продолжать проходить цикл while.Затем, когда вы захотите остановить цикл while, вы можете просто выполнить touch /tmp/stop_loop, и цикл while остановится.

Я подозреваю, что isfile() должен быть достаточно эффективным, так что, может быть, это не так уж и плохо.

...