Каков правильный способ обработки (в python) IOError: Прерванный системный вызов, вызванный multiprocessing.Queue.get

Когда я использую multiprocessing.Queue.get, я иногда получаю исключение из-за EINTR.

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

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

Как я могу отличить эти два?

заранее спасибо

2 Solutions collect form web for “Каков правильный способ обработки (в python) IOError: Прерванный системный вызов, вызванный multiprocessing.Queue.get”

Ошибка EINTR может быть возвращена из многих системных вызовов, когда приложение получает сигнал, ожидая другого ввода. Обычно эти сигналы могут быть довольно мягкими и уже обрабатываться Python, но основной системный вызов по-прежнему заканчивается прерыванием. При кодировании на C / C ++ это одна из причин, почему вы не можете полностью полагаться на такие функции, как sleep() . Библиотеки Python иногда обрабатывают этот код ошибки внутри, но, очевидно, в этом случае они не являются.

Вам может быть интересно прочитать эту тему, которая обсуждает эту проблему.

Общий подход к EINTR состоит в том, чтобы просто обработать ошибку и снова повторить операцию – это должно быть безопасным способом сделать метод get() в очереди. Возможно, что-то подобное, передавая очередь в качестве параметра и заменяя использование метода get() в очереди:

 import errno def my_queue_get(queue, block=True, timeout=None): while True: try: return queue.get(block, timeout) except IOError, e: if e.errno != errno.EINTR: raise # Now replace instances of queue.get() with my_queue_get(queue), with other # parameters passed as usual. 

Как правило, вам не нужно беспокоиться об EINTR в программе Python, если вы не знаете, что ожидаете определенный сигнал (например, SIGHUP ), и вы установили обработчик сигнала, который устанавливает флаг и полагается на основную часть код, чтобы поднять флаг. В этом случае вам может потребоваться выйти из цикла и проверить флаг сигнала, если вы получаете EINTR .

Однако, если вы не используете какую-либо обработку сигналов, вы должны просто игнорировать EINTR и повторять свою операцию – если сам Python должен что-то сделать с сигналом, который он должен был обработать в обработчике сигналов.

Старый вопрос, современное решение: с Python 3.5 замечательный PEP 475 – системные вызовы Retry, не соответствующие EINTR , были реализованы и решают проблему для вас. Вот реферат:

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

По системным вызовам мы имеем в виду функции, открытые стандартной библиотекой C, относящиеся к I / O или обработке других системных ресурсов.

В принципе, система будет ловить и повторить для вас фрагмент кода, который не прошел с EINTR поэтому вам больше не придется его обрабатывать. Если вы ориентируетесь на более старую версию, то while True loop все еще остается. Обратите внимание, что если вы используете Python 3.3 или 3.4, вы можете поймать выделенное исключение InterruptedError вместо того, чтобы ловить IOError и проверять EINTR .

Interesting Posts

Преобразование в Jython проекта Python 3.5 – UnicodeDecodeError: кодек Unicodeescape не может декодировать байты в позиции 4-10: незаконный символ Unicode

Печатать текст перед вызовом input () в python

Невозможно найти мой ПИТОНПАТ

NumPy C-API: преобразовать тип объекта в тип номера

Есть ли разница между «raise exception ()» и «raise exception» без скобок?

Безопасное создание новых приложений в Django OAuth Toolkit

Как я могу выяснить и получить доступ к подклассам предупреждения pandas?

Настройка пути python для sublimerepl из возвышенного текста?

Развертывание служб разных языков для одного и того же приложения

Кросс-платформенный способ получения PID по имени процесса в python

конвертировать lxml в селектор scrapy xxs

Есть ли что-то похожее на «рейк-маршруты» в джанго?

Выбор записей Pandas DataFrame в течение многих лет в зависимости от диапазона месяца и дня

Почему моя программа Python выдает ошибку времени выполнения – NZEC (ненулевой код выхода)?

Как правильно настроить автоиндентификацию VIM для редактирования файлов Python – * .py

Python - лучший язык программирования в мире.