2011-02-10 10 views
35

Estoy programando una aplicación de usuario para un sistema Linux incorporado, y estoy usando las funciones comunes tales como abrir, cerrar, leer, ioctl, etc. para los dispositivos. Ahora, leí acerca de EINTR, indica que la función fue interrumpida por una señal, pero no estoy seguro acerca de las implicaciones. En todos los programas de ejemplo que tengo, a veces se hace, p. ioctl(), a veces no está hecho, p. leer(). Entonces, estoy un poco confundido.¿Cuándo verificar EINTR y repetir la llamada de función?

¿Cuándo comprobo preferiblemente EINTR y repito la llamada a la función?

+0

¿por qué quiere llamar a su función por segunda vez? después de que se manejó la interrupción, el control se devuelve a su aplicación/función – knittl

+0

Pregunta similar: http://stackoverflow.com/questions/3633844/question-on-signal-handling-interrupt-handling – stefangachter

Respuesta

11

Ver sigaction: http://pubs.opengroup.org/onlinepubs/009695399/functions/sigaction.html

SA_RESTART 
    This flag affects the behavior of interruptible functions; that is, those 
    specified to fail with errno set to EINTR. If set, and a function specified 
    as interruptible is interrupted by this signal, the function shall restart 
    and shall not fail with EINTR unless otherwise specified. If the flag is not 
    set, interruptible functions interrupted by this signal shall fail with errno 
    set to EINTR. 

Por defecto, usted tiene el comportamiento SA_RESTART, por lo que no tiene que preocuparse de EINTR, si usted no juega con las señales.

+1

Entonces, ¿mientras no use señales en mis aplicaciones de usuario, no tengo que preocuparme por EINTR? Pero, p. read() es una llamada al sistema, por lo tanto, ¿no es posible que read() pueda ser interrumpido por la señal? – stefangachter

+3

Después de leer un poco más de tiempo, llegué a la conclusión de que tenía que verificar las llamadas a sistemas interrumpidos, que SA_RESTART no tiene en cuenta. – stefangachter

+0

Después de todo, esto solo es importante dentro de un manejador de señal. Mientras no tenga un manejador de señal, no me importa. – stefangachter

3

¿Está su aplicación impulsada por eventos? (Lo que significa que su bucle principal incluye la llamada select()/epoll_wait()).

En una aplicación controlada por eventos, puede bloquear todas las señales y solo desbloquearlas durante la llamada pselect()/epoll_pwait(). De esta forma, el resto de su código nunca tendrá que tratar con EINTR.

1

Tuve un problema similar al esperar la entrada de una tubería con nombre con read().

He encontrado una explicación y una macro útil para las primitivas en GNU libc documentation: TEMP_FAILURE_RETRY

Ejemplo:

TEMP_FAILURE_RETRY (read_return = read((int)example_fifo, buffer, (size_t)n)); 
if (read_return==-1){ 
    fprintf(stderr, "reader.c: read_fifo: read(): %s \n", strerror(errno)); 
    fflush(stderr); 
} 
Cuestiones relacionadas