Как перезапускать потоки случае непредвиденных ошибок в Python?
Рассмотрим ситуацию, в которой потоки читают показаний нескольких датчиков одновременно. В случае возникновения ошибки ввода/вывода во время чтения показаний одного из датчиков или другого подобного сбоя встает необходимость перезапускать упавший поток.
Первое, что приходит в голову это просто проверить, жив ли поток, и перезапустить его, если он умер:
# как то так if not current_thread.isAlive(): current_thread.start()
Попробуем смоделировать ситуацию:
import threading, time def sensor_a(): while True: time.sleep(1) print(«Читаем показания датчика А») def sensor_b(): i = 0 while True: time.sleep(1) if i == 1: # имитируем ошибку при чтении датчика raise KeyboardInterrupt print(«Читаем показания датчика Б») i += 1 # словарь с потоки для чтения счетчиков # словарь необходим для их перезапуска thread_dict = ‘SENSOR_A’: threading.Thread(target=sensor_a, name=’SENSOR_A’), ‘SENSOR_B’: threading.Thread(target=sensor_b, name=’SENSOR_B’) > threads = [t for t in thread_dict.values()] # запускаем потоки for t in threads: t.start() # следим за потоками в реальном времени while True: # проходимся по объектам потоков for thread in threading.enumerate(): # если поток умер if not thread.isAlive(): print(f’Поток, читающий thread.name> умер’) # получаем из словаря `thread_dict` # поток по имени для его перезапуска restart = thread_dict[thread.name] # пытаемся перезапустить restart.start() # Читаем показания датчика А # Читаем показания датчика Б # Читаем показания датчика А # Exception in thread sensor_b: # Traceback (most recent call last): # . # KeyboardInterrupt # Поток, читающий SENSOR_B умер # Перезапуск потока SENSOR_B # Traceback (most recent call last): # . # RuntimeError: threads can only be started once # Читаем показания датчика А # Читаем показания датчика А # .
Вот и ответ на поставленный вопрос «RuntimeError: threads can only be started once» — потоки могут быть запущены только один раз! Другими словами потоки перезапускать НЕЛЬЗЯ.
Python-джедай #7 — Циклы
В такой ситуации правильней и проще вообще не позволять умирать потокам, ведь если потоки на самом деле рушатся, то следом может упасть и вся программа. Если в функции потока, какой-то блок кода может вызывает исключение, то лучше подстраховаться и просто ловить это исключение, а в качестве результата выдать например None .
Если код программы уже написан и работает, а править очень долго, то можно поступить вообще тривиально, обернув функцию потока в другую функцию, которая будет ловить все исключения подряд.
import threading, time def sensor_a(): while True: time.sleep(1) print(«Читаем показания датчика А») def sensor_b(): i = 0 while True: time.sleep(1) if i == 1: # имитируем падение датчика raise KeyboardInterrupt print(«Читаем показания датчика Б») i += 1 def threadwrap(threadfunc): def wrapper(): while True: try: threadfunc() except BaseException as e: th_name = threading.current_thread().name print(f’Падение потока датчика th_name>, перезапуск. ‘) return wrapper # словарь потоков thread_dict = ‘SENSOR_A’: threading.Thread(target=sensor_a, name=’SENSOR_A’), ‘SENSOR_B’: threading.Thread(target=sensor_b, name=’SENSOR_B’) > # создаем потоки threads = [t for t in thread_dict.values()] # запускаем потоки for t in threads: t.start() # Читаем показания датчика Б # Читаем показания датчика А # Падение потока датчика SENSOR_B, перезапуск. # Читаем показания датчика А # Читаем показания датчика А # Читаем показания датчика Б # Читаем показания датчика А # .
- КРАТКИЙ ОБЗОР МАТЕРИАЛА.
- Получение общих сведений о потоках, модуль threading.
- Класс Thread() модуля threading.
- Класс local() модуля threading.
- Класс Event() модуля threading.
- Класс Lock() модуля threading.
- Класс RLock() модуля threading.
- Класс Condition() модуля threading.
- Класс Semaphore() модуля threading.
- Класс Timer() модуля threading.
- Класс Barrier() модуля threading.
- Протокол управления контекстом в модуле threading.
- Трассировка и профилирование потоков модулем threading.
- Как перезапускать потоки?
Источник: docs-python.ru
Автозапуск программ на python
Как мне перезапустить код в Python?
У меня есть эта игра без скремблера, которая запускается только в CMD или оболочке python. Когда пользователь правильно или неправильно догадывается о слове, он говорит «нажмите любую клавишу, чтобы снова играть» Как мне заставить его начать все заново?
Brennan Hoeting 12 июль 2012, в 21:44
Поделиться
Используйте какой-то цикл .
Ghost 12 июль 2012, в 19:25
Поделиться:
6 ответов
Лучший ответ
У вас нет выхода программы после оценки ввода от пользователя; вместо этого сделайте это в цикле. Например, простой пример, который даже не использует функцию:
phrase = «hello, world» while input(«Guess the phrase: «) != phrase: print(«Incorrect.») # Evaluate the input here print(«Correct») # If the user is successful
Это выводит следующее: с указанием моего пользователя:
Guess the phrase: a guess Incorrect. Guess the phrase: another guess Incorrect. Guess the phrase: hello, world Correct
Это, очевидно, довольно просто, но логика звучит так же, как и вы. Немного более сложная версия которой, с определенными функциями для вас, чтобы увидеть, где будет входить ваша логика, может быть такой:
def game(phrase_to_guess): return input(«Guess the phrase: «) == phrase_to_guess def main(): phrase = «hello, world» while not game(phrase): print(«Incorrect.») print(«Correct») main()
Источник: overcoder.net
Блог
Убивайте и перезапускайте скрипт Python каждый день
- Post author: admin
- Запись опубликована: 15 января, 2022
- Post category: Вопросы по программированию
#python #python-3.x #twitterapi-python
Вопрос:
У меня есть код на Python, который извлекает данные Twitter через API потоковой передачи. Я хотел бы использовать отдельные файлы на каждый день, поэтому я хотел бы, чтобы скрипт работал в течение 24 часов, затем убил его и перезапустил, так как при перезапуске программы имя файла изменится.
Как я могу гарантировать, что сценарий остановится в 00:00 и сразу же перезапустится? Код можно найти ниже. Если у вас есть какие-либо другие идеи о том, как я могу ежедневно создавать новый текстовый файл, это было бы еще лучше.
import tweepy import datetime key_words = [«xx»] twitter_data_title = «».join([xx, «_», date_today, «.txt»]) class TwitterStreamer(): def __init__(self): pass def stream_tweets(self, twitter_data_title, key_words): listener = StreamListener(twitter_data_title) auth = tweepy.OAuthHandler(api_key, api_secret_key) auth.set_access_token(access_token, access_secret_token) stream = tweepy.Stream(auth, listener) stream.filter(track=key_words) class StreamListener(tweepy.StreamListener): def __init__(self, twitter_data_title): self.fetched_tweets_filename = twitter_data_title def on_data(self, data): try: print(data) with open(self.fetched_tweets_filename, ‘a’) as tf: tf.write(data) return True except BaseException as e: print(«Error on_data %s» % str(e)) return True def on_exception(self, exception): print(‘exception’, exception) stream_tweets(twitter_data_title, key_words) def on_error(self, status): print(status) def stream_tweets(twitter_data_title, key_words): listener = StreamListener(twitter_data_title) auth = tweepy.OAuthHandler(api_key, api_secret_key) auth.set_access_token(access_token, access_secret_token) stream = tweepy.Stream(auth, listener) stream.filter(track=key_words) if __name__ == ‘__main__’: twitter_streamer = TwitterStreamer() twitter_streamer.stream_tweets(twitter_data_title, key_words)
1. У Python нет лучших методов освобождения памяти, поэтому лучше использовать кронджобы скриптов оболочки для запуска и уничтожения python.
2. Задания / запланированные задачи в зависимости от вашей операционной системы. В идеале используйте модуль ведения журнала для настройки журналов и при перезапуске просто добавьте _today дату в качестве имени файла
3. Используйте sys.exit(0) для выхода из вашего сценария.
Ответ №1:
Похоже, что «блокирующий» код в вашем примере взят из другой библиотеки, поэтому у вас нет возможности (легко) изменить внутренний цикл, чтобы проверить условие и выйти.
Использование фонового процесса (Не идеально)
Вы можете изменить точку входа, чтобы запустить код в фоновом режиме, и проверить, должен ли был измениться заголовок файла:
from multiprocessing import Process from time import sleep . if __name__ == «__main__»: twitter_streamer = TwitterStreamer() twitter_data_title, process = None, None while True: new_data_title = «».join([xx, «_», str(datetime.date.today()), «.txt»]) if new_data_title == twitter_data_title: # Nothing to do. sleep(60) # Sleep for a minute continue # And check again # Set the new title. twitter_data_title = new_data_title # If the process is already running, terminate and join it. if process is not None: process.terminate() process.join() process = Process(target=twitter_streamer.stream_tweets, args=[twitter_data_title, key_words]) process.start()
Меняющийся StreamListener
Лучшей альтернативой, вероятно, было бы закодировать информацию о дате в StreamListener . Вместо передачи имени файла ( twitter_data_title ) передайте префикс файла ( xx из вашего примера) и создайте имя файла в свойстве:
Поскольку StreamListener.on_data захватывает имя файла self.fetched_tweets_filename , это должно означать, что твиты записываются в новый файл при изменении даты.
Ответ №2:
Я бы добавил это в ваш код:
from threading import Timer def stopTheScript(): exec(open(«anotherscript.py»).read()) exit() Timer(86400, stopTheScript).start() #86400 s = 24 h
Вам также может понравиться
Node.js — Получение домена / URL клиента, запрашивающего доступ
5 апреля, 2023
Перенаправить Stderr в micropython?
29 октября, 2022
Есть файл JSON на сервере с массивом объектов и хотите отправить в него объект с помощью fs.appendFile
12 мая, 2023
- О нас
- Онлайн игры
- Конвертеры
- Base64 конвертер онлайн
- Оформление кода JavaScript CSS HTML Онлайн
- URL Encoder (кодировщик) / Decoder (декодировщик) онлайн
- Конвертер регистров
- Рассчитать количество дней между датами
- Генератор ключей и паролей
- Генератор QR кодов
- Преобразование времени
- Преобразование микросекунд в секунды
- Преобразование микросекунд в миллисекунды
- Преобразование миллисекунд в микросекунды
- Преобразование миллисекунд в секунды
- Преобразование миллисекунд в минуты
- Преобразование миллисекунд в часы
- Преобразователь миллисекунд в дату
- Преобразование секунд в миллисекунды
- Преобразование секунд в минуты
- Преобразование секунд в часы
- Преобразование секунд в дни
- Преобразование минут во время
- Преобразование минут в миллисекунды
- Преобразование минут в секунды
- Преобразование минут в часы
- Преобразование часов в миллисекунды
- Преобразование часов в секунды
- Преобразование часов в минуты
- Преобразование часов в дни
- Преобразование дней в часы
- Преобразование из часы в недели
- Конвертация из недели в часы
- Через несколько часов калькулятор
- Преобразование времени AM/PM в 24-часовое
- Преобразование Военного Времени
- Время до десятичного калькулятора
- Безопасность
- Финансы
- Энциклопедия
Источник: programbox.ru