linux linux-kernel multitasking

¿Qué significa decir "linux kernel es preventivo"?



linux-kernel multitasking (8)

Leí que el kernel de Linux es preventivo, que es diferente de la mayoría de los kernels de Unix. Entonces, ¿qué significa realmente para un kernal ser preventivo?

Algunas analogías o ejemplos serían mejores que la explicación teórica pura.


Antes de la versión 2.5.4 del kernel de Linux, el kernel de Linux no era preferente, lo que significa que un proceso que se ejecuta en modo kernel no se puede mover fuera del procesador hasta que él mismo abandone el procesador o comience a esperar a que se complete la operación de entrada y salida.

Generalmente, un proceso en modo de usuario puede entrar en modo kernel utilizando llamadas al sistema. Anteriormente, cuando el kernel no era preventivo, un proceso de prioridad más baja podía invertir un proceso de prioridad más alta al denegarle el acceso al procesador llamando repetidamente las llamadas al sistema y permaneciendo en el modo kernel. Incluso si el intervalo de tiempo del proceso de menor prioridad expirara, continuaría ejecutándose hasta que completara su trabajo en el kernel o renunciara voluntariamente al control. Si el proceso de mayor prioridad que espera para ejecutarse es un editor de texto en el que el usuario está escribiendo o un reproductor de MP3 listo para rellenar su búfer de audio, el resultado es un rendimiento interactivo deficiente. De esta manera, el kernel no preventivo fue un gran inconveniente en ese momento.


Creo que se convirtió en preventivo de 2.6. preventivo significa cuando un nuevo proceso está listo para ejecutarse, la CPU se asignará al nuevo proceso, no necesita que el proceso en ejecución sea cooperativo y renuncie a la CPU.


El kernel de Linux es monolítico y le da un poco de tiempo de computación a todo el proceso en ejecución de forma secuencial. Significa que los procesos (p. Ej., Los programas) no se ejecutan de forma concurrente, pero se les da un intervalo de tiempo dado regularmente para ejecutar su lógica. El problema principal es que cierta lógica puede tardar más tiempo en terminar y evitar que el kernel permita el siguiente proceso. Esto se traduce en el sistema "retrasos".

Un kernel preemtive tiene la capacidad de cambiar de contexto . Esto significa que puede detener un proceso "colgado" incluso si no está terminado, y dar el tiempo de cálculo al siguiente proceso como se esperaba. El proceso de "colgar" continuará ejecutándose cuando llegue su hora sin ningún problema.

Prácticamente, significa que el kernel tiene la capacidad de realizar tareas en tiempo real, lo que es particularmente interesante para la grabación y edición de audio.

El distrito de estudio de ubuntu incluye un kernel preventivo y un paquete de software gratuito de calidad dedicado a la edición de audio y video.


El kernel de Linux es preventivo significa que el kernel admite la preferencia.

Por ejemplo, hay dos procesos P1 (prioridad más alta) y P2 (prioridad más baja) que están haciendo llamadas al sistema de lectura y se están ejecutando en modo de núcleo. Supongamos que P2 se está ejecutando y está en modo kernel y que P2 está programado para ejecutarse.

Si está disponible la preferencia de kernel, entonces la preferencia puede ocurrir en el nivel del kernel, es decir, P2 se puede anular y, a modo de suspensión, y el P1 puede continuar ejecutándose.

Si la preferencia de kernel no está disponible, ya que P2 está en modo kernel, el sistema simplemente espera hasta que P2 se complete y luego


Imagina la simple vista de la multitarea preventiva. Tenemos dos tareas de usuario, las cuales se ejecutan todo el tiempo sin usar E / S ni realizar llamadas al kernel. Estas dos tareas no tienen que hacer nada especial para poder ejecutarse en un sistema operativo multitarea. El kernel, generalmente basado en una interrupción de temporizador, simplemente decide que es hora de que una tarea se detenga para permitir que otra se ejecute. La tarea en cuestión es completamente inconsciente de que algo sucedió.

Sin embargo, la mayoría de las tareas realizan solicitudes ocasionales del kernel a través de syscalls. Cuando esto sucede, existe el mismo contexto de usuario, pero la CPU está ejecutando el código del kernel en nombre de esa tarea.

Los kernels de Linux más antiguos nunca permitirían la prioridad de una tarea mientras estaba ocupado ejecutando el código del kernel. (Tenga en cuenta que las operaciones de E / S siempre se vuelven a programar de manera voluntaria. Estoy hablando de un caso en el que el código del kernel tiene una operación intensiva de CPU, como ordenar una lista).

Si el sistema permite que se anule la tarea mientras se ejecuta el código del kernel, entonces tenemos lo que se llama un "kernel preventivo". Tal sistema es inmune a los retrasos impredecibles que pueden encontrarse durante las llamadas al sistema, por lo que podría ser más adecuado para tareas integradas o en tiempo real.

Por ejemplo, si en una CPU en particular hay dos tareas disponibles, y una toma un syscall que tarda 5 ms en completarse, y la otra es una aplicación de reproductor de MP3 que necesita alimentar el canal de audio cada 2 ms, es posible que escuche un sonido entrecortado.

El argumento en contra de la preferencia es que todo el código del kernel que podría llamarse en el contexto de la tarea debe poder sobrevivir a la preferencia. Hay muchos códigos de controladores de dispositivos deficientes, por ejemplo, que podrían estar mejor si siempre pueden completar una operación antes. permitiendo que alguna otra tarea se ejecute en ese procesador. (Con los sistemas multiprocesador, la regla en lugar de la excepción en estos días, todo el código del kernel debe ser reentrante, por lo que el argumento no es tan relevante hoy en día). Además, si se pudiera lograr el mismo objetivo, mejorará los syscalls con errores. La latencia, tal vez la prevención es innecesaria.

Un compromiso es CONFIG_PREEMPT_VOLUNTARY, que permite un cambio de tarea en ciertos puntos dentro del kernel, pero no en todas partes. Si solo hay un pequeño número de lugares donde el código del kernel podría atascarse, esta es una forma económica de reducir la latencia y mantener la complejidad manejable.


La preferencia permite que el kernel dé la IMPRESIÓN del paralelismo: solo tiene un procesador (digamos hace una década), pero siente que todos sus procesos se ejecutan de forma simultánea. Esto se debe a que el núcleo anticipa (es decir, elimina la ejecución) la ejecución de un proceso para asignarlo al siguiente (tal vez de acuerdo con su prioridad).

EDITAR. Los núcleos no preventivos esperan que los procesos devuelvan la mano (es decir, durante las llamadas al sistema), por lo que si su proceso calcula una gran cantidad de datos y no llama a ningún tipo de función de yield , los otros procesos no podrán ejecutarse para ejecutar sus llamadas. Se dice que dichos sistemas son cooperativos porque solicitan la cooperación de los procesos para garantizar la equidad del tiempo de ejecución

EDIT 2 El objetivo principal de la prevención es mejorar la reactividad del sistema entre múltiples tareas, por lo que es bueno para los usuarios finales, mientras que, por otro lado, los servidores desean lograr el máximo rendimiento, por lo que no lo necesitan: (desde la configuración del kernel de Linux)


Los núcleos tradicionales de Unix tenían un solo bloqueo, que estaba sujeto a un hilo mientras se ejecutaba el código del núcleo. Por lo tanto, ningún otro código del núcleo podría interrumpir ese hilo.

Esto hizo que el diseño del kernel fuera más fácil, ya que sabía que mientras un hilo usaba recursos del kernel, ningún otro hilo lo era. Por lo tanto, los diferentes hilos no pueden desordenar el trabajo de los demás.

En sistemas de un solo procesador esto no causa demasiados problemas.

Sin embargo, en sistemas multiprocesador, podría tener una situación en la que varios subprocesos en diferentes procesadores o núcleos quisieran ejecutar el código del kernel al mismo tiempo. Esto significa que, dependiendo del tipo de carga de trabajo, podría tener muchos procesadores, pero todos pasan la mayor parte del tiempo esperándose el uno al otro.

En Linux 2.6, los recursos del kernel se dividieron en unidades mucho más pequeñas, protegidas por bloqueos individuales, y el código del kernel se revisó para asegurarse de que los bloqueos solo se mantenían mientras los recursos correspondientes estaban en uso. Así que ahora los diferentes procesadores solo tienen que esperarse entre ellos si desean acceder al mismo recurso (por ejemplo, recurso de hardware).


Significa que el programador del sistema operativo es libre de suspender la ejecución de los procesos en ejecución para entregar la CPU a otro proceso cuando lo desee; la forma normal de hacer esto es dar a cada proceso que está esperando a la CPU un "cuanto" de tiempo de CPU para ejecutarse. Una vez que ha expirado, el programador retoma el control (y el proceso en ejecución no puede evitar esto) para dar otro cuanto a otro proceso.

Este método a menudo se compara con la multitarea cooperativa, en la cual los procesos mantienen la CPU todo el tiempo que necesitan, sin ser interrumpidos, y para permitir que otras aplicaciones se ejecuten, tienen que llamar explícitamente a algún tipo de función de "rendimiento"; naturalmente, para evitar dar la sensación de que el sistema está atascado, las aplicaciones de buen comportamiento producirán la CPU a menudo. Aún así, si hay un error en una aplicación (por ejemplo, un bucle infinito sin llamadas de rendimiento), todo el sistema se bloqueará, ya que el programa defectuoso conserva completamente la CPU.

Casi todos los sistemas operativos de escritorio recientes utilizan multitarea preventiva, lo que, incluso si es más caro en términos de recursos, es en general más estable (es más difícil para una aplicación defectuosa de sigle colgar todo el sistema, ya que el sistema operativo siempre tiene el control). Por otro lado, cuando los recursos son limitados y se espera que la aplicación se comporte bien, se utiliza la multitarea cooperativa. Windows 3 era un sistema operativo multitarea cooperativo; Un ejemplo más reciente puede ser RockBox, un reemplazo de firmware PMP de código abierto.