GNU/Linux >> Tutoriales Linux >  >> Linux

¿Qué es un proceso ininterrumpido?

Cuando un proceso está en modo usuario, puede interrumpirse en cualquier momento (cambiando al modo kernel). Cuando el núcleo vuelve al modo de usuario, comprueba si hay señales pendientes (incluidas las que se utilizan para eliminar el proceso, como SIGTERM y SIGKILL ). Esto significa que un proceso solo se puede eliminar al volver al modo de usuario.

La razón por la que no se puede eliminar un proceso en modo kernel es que podría corromper las estructuras del kernel utilizadas por todos los demás procesos en la misma máquina (de la misma manera que eliminar un subproceso puede corromper las estructuras de datos utilizadas por otros subprocesos en el mismo proceso) .

Cuando el núcleo necesita hacer algo que podría llevar mucho tiempo (esperar en una canalización escrita por otro proceso o esperar a que el hardware haga algo, por ejemplo), se duerme marcándose a sí mismo como dormido y llamando al programador para cambiar a otro. proceso (si no hay un proceso que no esté inactivo, cambia a un proceso "ficticio" que le dice a la CPU que disminuya un poco la velocidad y se sienta en un bucle:el bucle inactivo).

Si se envía una señal a un proceso durmiente, debe despertarse antes de que regrese al espacio del usuario y, por lo tanto, procese la señal pendiente. Aquí tenemos la diferencia entre los dos tipos principales de sueño:

  • TASK_INTERRUPTIBLE , el sueño interrumpible. Si una tarea está marcada con esta bandera, está inactiva, pero puede despertarse mediante señales. Esto significa que el código que marcó la tarea como inactiva está esperando una posible señal y, después de que se despierte, la buscará y regresará de la llamada al sistema. Una vez que se maneja la señal, la llamada al sistema puede potencialmente reiniciarse automáticamente (y no entraré en detalles sobre cómo funciona).
  • TASK_UNINTERRUPTIBLE , el sueño ininterrumpido. Si una tarea está marcada con este indicador, no espera que la despierte nada más que lo que esté esperando, ya sea porque no se puede reiniciar fácilmente o porque los programas esperan que la llamada al sistema sea atómica. Esto también se puede usar para los sueños que se sabe que son muy cortos.

TASK_KILLABLE (mencionado en el artículo de LWN vinculado por la respuesta de ddaa) es una nueva variante.

Esto responde a tu primera pregunta. En cuanto a su segunda pregunta:no puede evitar los sueños ininterrumpidos, son algo normal (sucede, por ejemplo, cada vez que un proceso lee/escribe desde/hacia el disco); sin embargo, deberían durar solo una fracción de segundo. Si duran mucho más, generalmente significa un problema de hardware (o un problema de controlador de dispositivo, que se ve igual en el kernel), donde el controlador de dispositivo está esperando que el hardware haga algo que nunca sucederá. También puede significar que está usando NFS y que el servidor NFS está inactivo (está esperando que el servidor se recupere; también puede usar la opción "intr" para evitar el problema).

Finalmente, la razón por la que no puede recuperarse es la misma razón por la que el núcleo espera hasta volver al modo de usuario para enviar una señal o eliminar el proceso:podría corromper las estructuras de datos del núcleo (el código que espera en una suspensión interrumpible puede recibir un error que le dice para volver al espacio del usuario, donde el proceso se puede eliminar; el código que espera en un sueño ininterrumpido no espera ningún error).


Los procesos ininterrumpibles NORMALMENTE esperan E/S después de un fallo de página.

Considere esto:

  • El subproceso intenta acceder a una página que no está en el núcleo (ya sea un ejecutable cargado por demanda, una página de memoria anónima que se ha intercambiado o un archivo mmap() cargado por demanda, que son casi lo mismo)
  • El núcleo ahora está (intentando) cargarlo
  • El proceso no puede continuar hasta que la página esté disponible.

El proceso/tarea no se puede interrumpir en este estado, porque no puede manejar ninguna señal; si lo hiciera, ocurriría otra falla en la página y volvería a estar donde estaba.

Cuando digo "proceso", en realidad me refiero a "tarea", que en Linux (2.6) se traduce aproximadamente como "subproceso" que puede o no tener una entrada individual de "grupo de subprocesos" en /proc

En algunos casos, puede estar esperando durante mucho tiempo. Un ejemplo típico de esto sería donde el archivo ejecutable o mmap'd está en un sistema de archivos de red donde el servidor ha fallado. Si la E/S finalmente tiene éxito, la tarea continuará. Si finalmente falla, la tarea generalmente obtendrá un SIGBUS o algo así.


Un proceso ininterrumpible es un proceso que se encuentra en una llamada al sistema (función del núcleo) que no puede ser interrumpido por una señal.

Para comprender lo que eso significa, debe comprender el concepto de una llamada al sistema interrumpible. El ejemplo clásico es read() . Esta es una llamada al sistema que puede llevar mucho tiempo (segundos) ya que potencialmente puede implicar hacer girar un disco duro o mover cabezas. Durante la mayor parte de este tiempo, el proceso estará inactivo, bloqueándose en el hardware.

Mientras el proceso está inactivo en la llamada al sistema, puede recibir una señal asíncrona de Unix (por ejemplo, SIGTERM), luego sucede lo siguiente:

  • La llamada al sistema finaliza prematuramente y está configurada para devolver -EINTR al espacio del usuario.
  • Se ejecuta el controlador de señal.
  • Si el proceso aún se está ejecutando, obtiene el valor de retorno de la llamada del sistema y puede volver a realizar la misma llamada.

Regresar antes de la llamada al sistema permite que el código de espacio de usuario altere inmediatamente su comportamiento en respuesta a la señal. Por ejemplo, terminar limpiamente en reacción a SIGINT o SIGTERM.

Por otro lado, algunas llamadas al sistema no pueden interrumpirse de esta manera. Si la llamada del sistema se detiene por alguna razón, el proceso puede permanecer indefinidamente en este estado indestructible.

LWN publicó un buen artículo que abordó este tema en julio.

Para responder a la pregunta original:

  • Cómo evitar que esto suceda:descubra qué controlador le está causando problemas y deje de usarlo o conviértase en un hacker del kernel y arréglelo.

  • Cómo matar un proceso ininterrumpible sin reiniciar:de alguna manera hacer que la llamada al sistema termine. Con frecuencia, la manera más efectiva de hacer esto sin presionar el interruptor de encendido es tirar del cable de alimentación. También puede convertirse en un hacker del kernel y hacer que el controlador use TASK_KILLABLE, como se explica en el artículo de LWN.


A su tercera pregunta:creo que puede eliminar los procesos ininterrumpibles ejecutando sudo kill -HUP 1 .Reiniciará init sin finalizar los procesos en ejecución y después de ejecutarlo, mis procesos ininterrumpidos desaparecieron.


Linux
  1. Qué proceso está usando todo mi disco IO

  2. ¿Qué hacer cuando Ctrl + C no puede matar un proceso?

  3. ¿Cuál es la definición de una sesión en Linux?

  4. ¿Qué es un comando para encontrar la prioridad del proceso en Linux?

  5. ¿Determinar en qué grupo(s) se encuentra un proceso en ejecución?

¿Qué indica esta estadística de proceso?

SIGTERM vs SIGKILL:¿Cuál es la diferencia?

¿Qué proceso está consumiendo ptys en mi servidor Linux?

¿Qué es un proceso detenido en Linux?

Encuentra qué proceso está modificando un archivo

¿Qué son las señales pendientes?