2010-05-05 14 views
8

En Linux, cuando realiza una llamada de E/S de bloqueo como leer o aceptar, ¿qué sucede realmente?¿Cómo funciona realmente el bloqueo de I/O de Linux?

Mis pensamientos: el proceso se saca de la cola de ejecución, se pone en estado de espera o bloqueo en alguna cola de espera. Luego, cuando se realiza una conexión tcp (para aceptar) o el disco duro está listo o algo para leer un archivo, se produce una interrupción de hardware que permite que esos procesos esperen a que se activen y se ejecuten (en el caso de un archivo leído, ¿cómo funciona? Linux sabe qué procesos despertar, ya que podría haber muchos procesos esperando en diferentes archivos?). O tal vez en lugar de interrupciones de hardware, el proceso individual en sí mismo sondea para verificar la disponibilidad. No estoy seguro, ¿ayuda?

+0

Más o menos, ha puesto el dedo en la cabeza (a excepción de la última observación, no hay votación, en su mayor parte). La multiplexión entre múltiples camareros y archivos la realiza el kernel, que es un proceso invisible que coordina cosas como esta en nombre de todos los demás procesos. –

Respuesta

0

leyeron: http://www.minix3.org/doc/

Es una explicación muy clara, muy fácil de entender. Por lo general, también se aplica a Linux.

0

effectivly el método sólo se devuelve cuando el archivo está listo para leer, cuando los datos están en un socket, cuando ha llegado una conexión ...

Para asegurarse de que puede volver inmediatamente es probable que desee utilizar el Select llamada del sistema para encontrar un descriptor de archivo listo.

11

Cada dispositivo Linux parece estar implementado de forma ligeramente diferente, y la manera preferida parece variar cada pocos Linux libera a medida que se añaden características del núcleo más seguros/más rápido, pero en general:

controlador
  1. El dispositivo crea leer y escribir colas de espera para un dispositivo.
  2. Cualquier secuencia de proceso que desee esperar para E/S se coloca en la cola de espera apropiada. Cuando se produce una interrupción , el controlador despierta uno o más hilos de espera . (Obviamente, los subprocesos no se ejecutan inmediatamente ya que estamos en el contexto de interrupción , pero se agregan a la cola de programación del kernel ).
  3. Cuando programado por el kernel, el hilo comprueba si las condiciones son correctas para que proceda; si no es así, vuelve a la cola de espera.

Un ejemplo típico (ligeramente simplificada):

En el controlador en la inicialización:

init_waitqueue_head(&readers_wait_q); 

En la función de lectura de un conductor:

if (filp->f_flags & O_NONBLOCK) 
    { 
     return -EAGAIN; 
    } 
    if (wait_event_interruptible(&readers_wait_q, read_avail != 0)) 
    { 
     /* signal interrupted the wait, return */ 
     return -ERESTARTSYS; 
    } 
    to_copy = min(user_max_read, read_avail); 
    copy_to_user(user_buf, read_ptr, to_copy); 

A continuación, el controlador de interrupción solo problemas:

wake_up_interruptible(&readers_wait_q); 

Tenga en cuenta que wait_event_interruptible() es una macro que oculta un bucle que comprueba una condición - read_avail != 0 en este caso - y agrega repetidas veces a la cola de espera si se despierta cuando la condición no es verdadera.

Como se mencionó, hay una serie de variaciones, la principal es que si hay mucho trabajo para el manejador de interrupciones entonces hace el mínimo y retrasa el resto a una cola de trabajo o tasklet (generalmente conocida como la "mitad inferior") y es esto lo que activaría los hilos de espera.

Ver libro del controlador de dispositivo Linux para más detalles - pdf disponible aquí: http://lwn.net/Kernel/LDD3

Cuestiones relacionadas