starmap set_start_method parallel from python error-handling queue multiprocessing ioerror

set_start_method - ¿Cuál es la forma correcta de manejar(en python) IOError:[Errno 4] Llamada al sistema interrumpida, planteada por multiprocesamiento.Queue.get



python pool process (2)

Cuando uso multiprocessing.Queue.get, a veces recibo una excepción debido a EINTR.

Sé definitivamente que a veces esto sucede sin una buena razón (abro otro panel en un buffr tmux), y en tal caso me gustaría continuar trabajando y volver a intentar la operación.

Me imagino que en otros casos el error se debe a una buena razón y debería dejar de ejecutar o corregir algún error.

¿Cómo puedo distinguir los dos?

Gracias por adelantado


El error EINTR puede devolverse desde muchas llamadas al sistema cuando la aplicación recibe una señal mientras espera otra entrada. Normalmente, estas señales pueden ser bastante benignas y ya manejadas por Python, pero la llamada al sistema subyacente aún termina siendo interrumpida. Al hacer la codificación C / C ++, esta es una de las razones por las que no puede confiar completamente en funciones como sleep() . Las bibliotecas de Python a veces manejan este código de error internamente, pero obviamente en este caso no lo son.

Puede que le interese leer este hilo que trata este problema.

El enfoque general de EINTR es simplemente manejar el error y volver a intentar la operación nuevamente, esto debería ser algo seguro de hacer con el método get() en la cola. Se podría usar algo como esto, pasar la cola como parámetro y reemplazar el uso del método get() en la cola:

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.

Normalmente no debería tener que preocuparse por EINTR en un programa Python a menos que sepa que está esperando una señal particular (por ejemplo, SIGHUP ) y ha instalado un controlador de señal que establece un indicador y depende del cuerpo principal del código para recoger la bandera. En este caso, es posible que deba salir de su circuito y verificar el indicador de señal si recibe EINTR .

Sin embargo, si no está utilizando ningún manejo de señal, entonces debería ser capaz de simplemente ignorar EINTR y repetir su operación, si Python necesita hacer algo con la señal que ya debería haber manejado en el manejador de señal.


Una vieja pregunta, una solución moderna: a partir de Python 3.5, se ha implementado el maravilloso PEP 475 - Reintentar llamadas al sistema con EINTR y resuelve el problema por usted. Aquí está el resumen:

Los contenedores de llamadas al sistema que se proporcionan en la biblioteca estándar se deben reintentar automáticamente cuando fallen con EINTR , para liberar el código de la aplicación de la carga de hacerlo.

Por llamadas al sistema, nos referimos a las funciones expuestas por la biblioteca estándar C perteneciente a E / S o al manejo de otros recursos del sistema.

Básicamente, el sistema detectará y reintentará un código que falló con EINTR por lo que ya no tendrá que manejarlo. Si se dirige a una versión anterior, while True loop todavía es el camino a seguir. Sin embargo, tenga en cuenta que si está utilizando Python 3.3 o 3.4, puede capturar la excepción dedicada InterruptedError lugar de detectar IOError y buscar EINTR .