Estados de Proceso de Linux


En Linux, ¿qué sucede con el estado de un proceso cuando necesita leer bloques de un disco? Está bloqueado? Si es así, ¿cómo se elige otro proceso para ejecutar?

Author: Blair, 2009-09-25

8 answers

Mientras se espera read() o write() a/desde un descriptor de archivo, el proceso se pondrá en un tipo especial de suspensión, conocido como "D" o "Suspensión de disco". Esto es especial, porque el proceso no puede ser asesinado o interrumpido mientras esté en tal estado. Un proceso que espera un retorno de ioctl () también se pondría en suspensión de esta manera.

Una excepción a esto es cuando un archivo (como un terminal u otro dispositivo de caracteres) se abre en modo O_NONBLOCK, pasado cuando se asume que un dispositivo (como como módem) necesitará tiempo para inicializar. Sin embargo, usted indicó dispositivos de bloqueo en su pregunta. Además, nunca he probado un ioctl() que es probable que se bloquee en un fd abierto en modo sin bloqueo (al menos no a sabiendas).

Cómo se elige otro proceso depende completamente del scheduler que esté utilizando, así como lo que otros procesos podrían haber hecho para modificar sus pesos dentro de ese scheduler.

Se sabe que algunos programas de espacio de usuario en ciertas circunstancias permanecen en este estado para siempre, hasta que se reinicie. Estos se agrupan típicamente con otros "zombies", pero el término no sería correcto ya que no están técnicamente extintos.

 73
Author: Tim Post,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-09 18:55:35

Cuando un proceso necesita obtener datos de un disco, efectivamente deja de ejecutarse en la CPU para permitir que otros procesos se ejecuten porque la operación puede tardar mucho tiempo en completarse: al menos 5ms buscan tiempo para un disco es común, y 5ms es 10 millones de ciclos de CPU, ¡una eternidad desde el punto de vista del programa!

Desde el punto de vista del programador (también dicho "en el espacio de usuario"), esto se llama llamada al sistema de bloqueo. Si llama a write(2) (que es un envoltorio libc delgado alrededor del llamada al sistema del mismo nombre), su proceso no se detiene exactamente en ese límite: continúa, en el lado del núcleo, ejecutando el código de llamada al sistema. La mayoría de las veces va hasta un controlador de disco específico (filename → filesystem/VFS → block device → device driver), donde un comando para obtener un bloque en el disco se envía al hardware adecuado: esta es una operación muy rápida la mayoría de las veces.

LUEGO el proceso se pone en estado de reposo (en el espacio del núcleo, el bloqueo se llama sleeping-nada es nunca 'bloqueado' desde el punto de vista del núcleo). Se despertará de nuevo una vez que el hardware finalmente haya obtenido los datos adecuados, entonces el proceso se marcará como runnable, programado y se ejecutará tan pronto como el programador lo permita.

Finalmente en el espacio de usuario, la llamada al sistema de bloqueo regresa con el estado y los datos adecuados, y el flujo del programa continúa.

Es posible invocar la mayoría de las llamadas al sistema de E/S en el modo sin bloqueo (véanse O_NONBLOCK en open(2) y fcntl(2)). En este caso, el sistema llama a return inmediatamente y solo informa sobre el envío adecuado de la operación del disco. El programador tendrá que comprobar explícitamente en un momento posterior si la operación se completó, con éxito o no, y obtener su resultado (por ejemplo, con select(2)). Esto se denomina programación asíncrona o basada en eventos.

La mayoría de las respuestas aquí mencionando el estado D (cuyo nombre exacto es TASK_UNINTERRUPTIBLE de los nombres de estado de Linux) son incorrectas. El D state es un modo de suspensión especial que solo se activa en una ruta de código de espacio del núcleo, cuando esa ruta de código no se puede interrumpir (porque sería muy complejo de programar), la mayoría de las veces con la esperanza de que se bloquearía muy pronto. Creo que la mayoría de los "estados D" son en realidad invisibles, son de muy corta duración y no pueden ser observados por herramientas de muestreo como 'top'.

Pero a veces se encontrará con esos procesos imposibles de matar en estado D en algunas situaciones. NFS es famoso por eso, y lo he encontrado muchas veces. Creo que hay un choque semántico entre algunas rutas de código VFS que asumen que siempre llegan a los discos locales y la detección rápida de errores (en SATA, un tiempo de espera de error sería de unos 100 ms), y NFS que en realidad obtiene datos de la red que es más resistente y tiene una recuperación lenta (un tiempo de espera TCP de 300 segundos es común). Lea este artículo para la solución cool introducida en Linux 2.6.25 con el estado TASK_KILLABLE. Antes de esto era había un hack donde se podía enviar señales a clientes de procesos NFS enviando un SIGKILL al hilo del kernel rpciod, pero olvídate de ese feo truco {

 121
Author: zerodeux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-12 09:10:22

Un proceso que realiza E/S se pondrá en estado D (suspensión ininterrumpida), que libera la CPU hasta que haya una interrupción de hardware que le diga a la CPU que vuelva a ejecutar el programa. Véase man ps para los otros estados de proceso.

Dependiendo de su kernel, hay un process scheduler, que realiza un seguimiento de una secuencia de procesos listos para ejecutarse. Junto con un algoritmo de programación, le dice al núcleo qué proceso asignar a qué CPU. Hay procesos de kernel y procesos de usuario a considerar. A cada proceso se le asigna un segmento de tiempo, que es una parte del tiempo de CPU que se le permite usar. Una vez que el proceso utiliza todo su segmento de tiempo, se marca como expirado y se le da menor prioridad en el algoritmo de programación.

En el núcleo 2.6, hay un programador de complejidad de tiempo O(1) , por lo que no importa cuántos procesos tenga en ejecución, asignará CPU en tiempo constante. Sin embargo, es más complicado, ya que 2.6 el preemption introducido y el equilibrio de carga de la CPU no es un algoritmo fácil. En cualquier caso, es eficiente y las CPU no permanecerán inactivas mientras espera la E/S.

 6
Author: user224579,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-10 06:43:19

Como ya han explicado otros, los procesos en estado "D" (sueño ininterrumpido) son responsables del cuelgue del proceso ps. A mí me ha pasado muchas veces con RedHat 6.directorios de inicio x y NFS montados automáticamente.

Para listar procesos en estado D puede usar los siguientes comandos:

cd /proc
for i in [0-9]*;do echo -n "$i :";cat $i/status |grep ^State;done|grep D

Para conocer el directorio actual del proceso y, puede ser, el disco NFS montado que tiene problemas puede usar un comando similar al siguiente ejemplo (reemplace 31134 con el sleeping número de proceso):

# ls -l /proc/31134/cwd
lrwxrwxrwx 1 pippo users 0 Aug  2 16:25 /proc/31134/cwd -> /auto/pippo

Encontré que dar el comando umount con el interruptor-f (force), al sistema de archivos nfs montado relacionado, fue capaz de activar el proceso de reposo:

umount -f /auto/pippo

El sistema de archivos no se desmontó, porque estaba ocupado, pero el proceso relacionado se activó y pude resolver el problema sin reiniciar.

 2
Author: Valerio Di Giampietro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-02 15:16:20

Asumiendo que su proceso es un solo subproceso, y que está utilizando E/S de bloqueo, su proceso se bloqueará a la espera de que la E/S se complete. El núcleo elegirá otro proceso para ejecutarlo mientras tanto basado en su amabilidad, prioridad, último tiempo de ejecución, etc. Si no hay otros procesos ejecutables, el núcleo no ejecutará ninguno; en su lugar, le dirá al hardware que la máquina está inactiva (lo que resultará en un menor consumo de energía).

Los procesos que están esperando que se complete la E/S normalmente se muestran en estado D en, por ejemplo, ps y top.

 1
Author: derobert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-25 06:24:48

Sí, la tarea se bloquea en la llamada al sistema read (). Otra tarea que está lista se ejecuta, o si no hay otras tareas listas, se ejecuta la tarea inactiva (para esa CPU).

Una lectura normal de disco bloqueante hace que la tarea entre en el estado "D" (como otros han señalado). Estas tareas contribuyen al promedio de carga, aunque no consuman la CPU.

Algunos otros tipos de IO, especialmente ttys y network, no se comportan de la misma manera - el proceso termina en estado " S " y puede ser interrumpido y no cuenta contra el promedio de carga.

 1
Author: MarkR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-25 21:57:51

Sí, las tareas en espera de IO se bloquean y se ejecutan otras tareas. La selección de la siguiente tarea es realizada por el programador de Linux .

 0
Author: Martin v. Löwis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-25 06:26:11

Generalmente el proceso se bloqueará. Si la operación de lectura está en un descriptor de archivo marcado como no bloqueante o si el proceso está utilizando IO asíncrono, no se bloqueará. Además, si el proceso tiene otros subprocesos que no están bloqueados, pueden continuar ejecutándose.

La decisión sobre qué proceso se ejecuta a continuación depende del planificador en el núcleo.

 0
Author: Benno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-25 06:26:58