2011-11-08 12 views
16

Esta es una pregunta de seguimiento al Is a successful send() "atomic"?, ya que creo que en realidad se trata de llamadas al sistema en general, no solo de envíos en tomas.¿Cuándo y cómo se interrumpen las llamadas al sistema?

¿Qué llamadas al sistema se pueden interrumpir, y cuando lo están, dónde se maneja la interrupción? Aprendí sobre SA_RESTART, pero no entiendo exactamente qué está pasando.

  • Si hago una llamada al sistema sin SA_RESTART, la llamada puede ser interrumpida por ningún tipo de interrupciones (por ejemplo, la entrada del usuario) que no es de mi solicitud, pero requiere el sistema operativo para abortar mi llamada y hacer algo ¿más? ¿O solo se ve interrumpido por señales que afectan directamente a mi proceso (CTRL + C, socket cerrado, ...)?

  • Al configurar SA_RESTART, ¿cuál es la semántica de un envío() o de cualquier otro syscall "lento"? ¿Siempre se bloqueará hasta que todos mis datos se transmitan o el socket se caiga, o puede regresar con un número más pequeño que el conteo en el parámetro send()?

  • ¿Dónde se está reiniciando? ¿El sistema operativo sabe que quiero que la llamada se reinicie ante cualquier interrupción, o se envía alguna señal a mi proceso y luego se maneja por código de la biblioteca? O debo hacerlo yo mismo, p. envuelva la llamada en un ciclo while y vuelva a intentar tantas veces como sea necesario?

Respuesta

9

llamadas del sistema pueden estar interrumpidas por cualquier signal, esto incluye señales, tales como SIGINT (generado por CTRL-C), SIGHUP, etc.

Cuando se establece SA_RESTART, un send() volverá (con la conteo enviado) si se transmitió cualquier dato antes de recibir la señal, devolverá un error EINTR si se estableció un tiempo de espera de envío (ya que no se pueden reiniciar), de lo contrario, se reiniciará send().

El reinicio de la llamada al sistema se implementa en el código de manejo de señal del kernel. La llamada al sistema devuelve internamente -ERESTARTSYS al detectar una señal pendiente (o una espera interrumpida por una señal), lo que hace que el código de manejo de señal restaure el puntero de instrucción y los registros relevantes al estado anterior a la llamada, haciendo que se repita la syscall.

+1

Esto solo significa las señales enviadas a mi proceso, ¿no? De alguna manera asumí que CUALQUIER interrupción del kernel que manejaba mi interrupción (una pulsación de tecla, movimiento del mouse, interrupción de temporizador, ...) haría que mi llamada volviera y que se enviara la señal. Un cambio de contexto durante la llamada al sistema no debe interferir con mi proceso de ninguna manera, además del tiempo, ¿no? – lxgr

+1

@lxgr, eso es correcto, el cambio de contexto no cancela las llamadas al sistema. –

Cuestiones relacionadas