2011-06-06 14 views
12

Mi programa pasa a través de un bucle de esta manera: los bloques de funcióninterrumpir bloqueado leer

... 
while(1){ 
    read(sockfd,buf,sizeof(buf)); 
    ... 
} 

La lectura cuando se está a la espera para la entrada, que pasa a ser de un enchufe. Quiero manejar SIGINT y básicamente decirle que detenga la función de lectura si está leyendo y luego llamar a una función arbitraria. ¿Cuál es la mejor manera de hacer esto?

Respuesta

14

De read(2):

EINTR The call was interrupted by a signal before any data 
      was read; see signal(7). 

Si usted enmienda el código para parecerse más a:

cont = 1; 
while (1 && cont) { 
    ret = read(sockfd, buf, sizeof(buf)); 
    if (ret < 0 && errno == EINTR) 
     cont = arbitrary_function(); 
} 

Esto permite arbitrary_function() decidir si el read(2) debe juzgado de nuevo o no.

actualización

Es necesario para manejar la señal con el fin de obtener el comportamiento de EINTRread(2):

#include<unistd.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<signal.h> 
#include<errno.h> 

int interrupted; 

void handle_int(num) { 
    interrupted = 1; 
} 

int main(void){ 
    char buf[9001]; 
    struct sigaction int_handler = {.sa_handler=handle_int}; 
    sigaction(SIGINT,&int_handler,0); 
    while(!interrupted){ 
    printf("interrupted: %d\n", interrupted); 
    if(read(0,buf,sizeof(buf))<0){ 
     if(errno==EINTR){ 
     puts("eintr"); 
     }else{ 
     printf("%d\n",errno); 
     } 
     puts("."); 
    } 
    } 
    puts("end"); 
    return 0; 
} 

Da salida:

$ ./foo 
interrupted: 0 
hello 
interrupted: 0 
^Ceintr 
. 
end 
+0

Con lo que nos ha facilitado, El envío de SIGINT (a través de Ctrl + C) solo termina el programa. – kaykun

+0

@kaykun, solo si esa es la última línea del programa. Puede agregar más líneas después del bloque 'while' que reinicia la transmisión, puede soltar ese cliente específico y continuar con el enlace principal de su programa, puede iniciar un shell interactivo con el usuario para preguntar qué acciones tomar a continuación ... nada dice que esto deba terminar el programa. – sarnold

+0

@sarnold Incorrecto, al menos para mí el programa termina cuando se envía SIGINT sin importar lo que agregue después del ciclo while, que es el mismo para casi todos los demás programas de línea de comandos. – kaykun

2

Cuando su proceso recibe una señal, read() regresará y el valor de errno se establecerá en EINTR.

Cuestiones relacionadas