Принудительное завершение потоков
У меня асинхронное приложение, которое парсит данные каждые N минут и записывает их в БД. Вместе с этим консоль принимает команды от пользователя (на вывод или экспорт данных в xlsx) - всё независимо друг от друга. При ручном завершении скрипта иногда вылетают ошибки, типа:
Exception ignored in: <module 'threading' from '/usr/lib/python3.10/threading.py'>
Traceback (most recent call last):
File "/usr/lib/python3.10/threading.py", line 1537, in _shutdown
atexit_call()
File "/usr/lib/python3.10/concurrent/futures/thread.py", line 31, in _python_exit
t.join()
File "/usr/lib/python3.10/threading.py", line 1096, in join
self._wait_for_tstate_lock()
File "/usr/lib/python3.10/threading.py", line 1116, in _wait_for_tstate_lock
if lock.acquire(block, timeout):
KeyboardInterrupt:
^C
У меня есть такое:
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\nВыполнение прервано пользователем.")
except Exception as e:
print(f"\nОшибка: {e}")
Оно исключает всё, кроме threading. В приложении я использую только asyncio.
В main запускается парсинг каждые N минут и консоль для ввода команд:
async def main():
# Запуск обновления данных отдельном таске
asyncio.create_task(update_data(a, b, c))
# Запуск интерфейса пользователя
await ui.run()
В update_data и методе интерфейса ui.run есть бесконечные циклы:
async def update_data(a, b, c):
while True:
# Ждем delay минут перед следующим обновлением
await asyncio.sleep(delay * 60)
try:
....................
async def run(self):
# метод принимает команды от пользователя
while True:
try:
cmd = await asyncio.get_event_loop().run_in_executor(None, input)
if cmd in self.command_dict:
await self.command_dict[cmd]()
continue
else:
print(self.help_message)
except EOFError:
break
Как принудительно завершить потоки или завершить их корректно? Ошибки не всегда появляются, думаю, это связанно с бесконечными циклами...