Есть ли лучший способ поймать «прерывание клавиатуры», чем бесконечный цикл с asyncio?

#python #python-asyncio

Вопрос:

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

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

 while True:  if condition_here:  break  else:  await asyncio.sleep(1)  

что действительно работает в ловле KeyboardInterrupts . Тем не менее, я не большой поклонник использования подобных циклов while и хотел бы избежать этого, если это вообще возможно.

Для некоторого примера кода вот то, что у меня есть в настоящее время (которое не улавливает прерывания до тех пор, пока поток не будет завершен):

 import asyncio import time from threading import Thread  def some_long_process():  time.sleep(60)  async def main():  thread = Thread(target=some_long_process)  thread.start()   # Doesn't work  loop = asyncio.get_event_loop()  await loop.run_in_executor(None, thread.join)  # await asyncio.wait([loop.run_in_executor(None, thread.join)])  # await asyncio.wait_for(loop.run_in_executor(None, thread.join), None)  # await asyncio.gather(asyncio.to_thread(thread.join))   # Works  # while thread.is_alive():  # await asyncio.sleep(1)  if __name__ == '__main__':  asyncio.run(main())  

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

Комментарии:

1. Я почти уверен, что цикл while asycnio.sleep действительно является самым простым и лучшим способом справиться с этим. По сути, вы хотите, чтобы ваш основной поток ждал какого-то события завершения, а затем использовал его для запуска другого процесса. Технически Python можно заставить функционировать подобным образом, управляемым событиями, но все модули, которые это делают, на самом деле просто вращаются в цикле while в фоновом режиме: с таким же успехом можно просто запустить цикл самостоятельно

2. @JonathanDBVanSchenck Хорошо, звучит неплохо. Я знаю, что все работает как цикл в бэкэнде (отсюда «цикл событий» lol), поэтому я надеялся просто использовать это вместо того, чтобы запускать внутри него свой собственный цикл. Спасибо.