Diseño e implementación del kernel de Linux - sincronización del kernel

  

sincronización del kernel

introducción a la sincronización

concepto de sincronización

sección crítica: también conocida como sección crítica, es acceso y El segmento de código que opera sobre datos compartidos.

Condiciones competitivas: cuando dos o más subprocesos se ejecutan simultáneamente en una sección crítica, constituyen una condición de carrera.

La sincronización evita la formación de condiciones competitivas en secciones críticas.

Si hay una operación atómica en la sección crítica (es decir, no se interrumpirá antes de que se complete la operación completa), entonces naturalmente no habrá condiciones de competencia. Sin embargo, en aplicaciones prácticas, el código en la sección crítica a menudo no es tan simple, por lo que para mantener la sincronización, se introduce el mecanismo de bloqueo. Pero habrá algunos problemas con las cerraduras.

Condición de interbloqueo generado: debe haber uno o más subprocesos de ejecución y uno o más recursos, cada uno de los cuales está esperando uno de los recursos, pero todos los recursos ya están ocupados. Así que los hilos se esperan, pero nunca liberan los recursos que ya tienen. Así que cualquier hilo no puede continuar, y se produce un punto muerto.

Bloqueo automático: si un subproceso de ejecución intenta adquirir un bloqueo que ya tiene, debe esperar a que se libere el bloqueo. Pero como está ocupado esperando este bloqueo, nunca tendrá la oportunidad de liberar el bloqueo y se producirá un interbloqueo.

La inanición es un fenómeno en el que un subproceso no puede obtener los recursos que necesita durante mucho tiempo y no puede ejecutarlo.

Causas de la concurrencia

Interrupción — — Las interrupciones pueden ocurrir de forma asíncrona en cualquier momento, es decir, puede interrumpir el código que se está ejecutando en cualquier momento.

Soft Interrupts and Tasklets — — El kernel puede activarse o programar interrupciones y tasklets en cualquier momento, interrumpiendo el código que se está ejecutando actualmente.

Prevención de kernel — — Debido a que el kernel es preventivo, las tareas en el kernel pueden ser sustituidas por otra tarea.

Sincronización de la suspensión y el espacio de usuario — — El proceso que se ejecuta en el kernel puede estar inactivo, lo que activa al programador y hace que se programe la ejecución de un nuevo proceso de usuario.

Multiprocesamiento simétrico — — dos o más procesadores pueden ejecutar código al mismo tiempo.

Reglas simples para evitar puntos muertos

El orden de bloqueo es la clave. Al usar bloqueos anidados, debe asegurarse de que los bloqueos se adquieran en el mismo orden, lo que evita los puntos muertos del tipo de abrazo mortal. Es mejor registrar el orden de los bloqueos para que otros puedan usarlos en este orden.

Evita que el hambre pase. Determine si la ejecución de este código terminará. Si A no sucede, ¿B tiene que esperar todo el tiempo?

No solicite el mismo bloqueo repetidamente.

Cuanto más complejo sea el esquema de bloqueo, más probable es que se produzca un interbloqueo. --- Diseño de estrés debe ser simple.

La granularidad del bloqueo

La granularidad del bloqueo se utiliza para describir el tamaño de los datos protegidos por el bloqueo. Un bloqueo demasiado grueso protege grandes bloques de datos, como todas las estructuras de datos de un subsistema, y ​​un bloqueo excesivamente delgado protege pequeños fragmentos de datos, como un elemento en una estructura de big data.

Al bloquear, no solo para evitar puntos muertos, sino también para considerar la granularidad del bloqueo.

La granularidad del bloqueo tiene un gran impacto en la escalabilidad del sistema. Al bloquear, considere si el bloqueo será utilizado con frecuencia por varios subprocesos.

Si es probable que el bloqueo se dispare con frecuencia, debe refinar la granularidad del bloqueo.

El refinamiento del bloqueo mejorará el rendimiento en el caso de los multiprocesadores.

Métodos de sincronización

Operaciones atómicas

Las operaciones atómicas se refieren a operaciones que no son interrumpidas por otras rutas de código durante la ejecución. El código del kernel puede llamarlas con seguridad. Sin ser interrumpido.

Las operaciones atómicas se dividen en operaciones atómicas enteras y operaciones atómicas de bits.

spinlock spin lock

La característica de un spin spin es que cuando un hilo adquiere un bloqueo, otros hilos que intentan adquirir el bloqueo esperan en un bucle para adquirir el bloqueo hasta que el bloqueo vuelva a estar disponible.

Dado que el hilo en realidad se enrolla para adquirir este bloqueo, causará una pérdida de tiempo de procesamiento de la CPU, por lo que es mejor usar el bloqueo de giro para la sección crítica que se puede procesar rápidamente.

Hay 2 puntos que deben tenerse en cuenta al utilizar los bloqueos de giro:

1. Los bloqueos de giro no son recursivos, y las solicitudes recursivas con el mismo bloqueo de giro se bloquearán.

2. Antes de que el hilo adquiera el bloqueo de giro, es necesario deshabilitar la interrupción en el procesador actual.
(Evitar el subproceso e interrumpir que adquiera el bloqueo para formar una condición de carrera) Por ejemplo, después de que el subproceso actual adquiera el bloqueo de giro, el controlador de interrupciones lo interrumpe en la sección crítica, y el controlador de interrupciones solo necesita adquirir el bloqueo, por lo que el controlador de interrupciones esperará la corriente. El hilo libera el bloqueo, y el hilo actual también está esperando la ejecución de la interrupción antes de ejecutar la sección crítica y liberar el código de bloqueo.

El uso de los bloqueos de giro en la mitad inferior de la gestión de interrupciones requiere un cuidado especial:

1. Cuando la mitad inferior procesa y el contexto del proceso comparte datos, la mitad inferior del procesamiento puede anticiparse al proceso. El código del contexto, por lo que el contexto del proceso debe prohibir la ejecución de la mitad inferior antes de bloquear los datos compartidos, y luego permitir la ejecución de la mitad inferior al desbloquear.

2. Cuando el controlador de interrupciones (mitad superior) y la mitad inferior procesan datos compartidos, el procesamiento de interrupciones (mitad superior) puede adelantarse a la ejecución de la mitad inferior y la mitad inferior se agrega a los datos compartidos. El procesamiento de interrupciones (mitad superior) está prohibido antes del bloqueo, y se permite la ejecución de interrupciones al desbloquear.

3. El mismo tasklet no puede ejecutarse al mismo tiempo, por lo que los datos compartidos en el mismo tasklet no necesitan estar protegidos.

4. Cuando se comparten datos en diferentes tasklets de clase, uno de los tasklets no necesita prohibir la ejecución de otros tasklets después de que se adquiera el bloqueo, porque no habrá preferencia de tasklet en el mismo procesador

5. Las interrupciones suaves del mismo tipo o tipos diferentes no necesitan deshabilitar la mitad inferior cuando se comparten datos, porque no habrá interrupciones suaves que se anulen entre sí en el mismo procesador.

Bloqueo giratorio de lectura-escritura

Si los datos protegidos por la sección crítica se pueden leer y escribir, las operaciones simultáneas pueden admitirse para lectura siempre que no haya una operación de escritura. Para este requisito de que solo las operaciones de escritura son mutuamente excluyentes, si aún usa un bloqueo de giro, obviamente no puede cumplir con este requisito (es un desperdicio para las operaciones de lectura). Para este propósito, el núcleo proporciona otro bloqueo de giro de lectura y escritura. El bloqueo de giro de lectura también se denomina bloqueo de giro compartido. El bloqueo de giro de escritura también se denomina bloqueo de giro exclusivo.

El bloqueo de giro de lectura-escritura es un mecanismo de bloqueo más pequeño que la granularidad del bloqueo de giro. Conserva el concepto de "giro", pero por escrito, solo puede haber un proceso de escritura como máximo. En términos de operaciones de lectura, puede haber varias unidades de ejecución de lectura al mismo tiempo. Por supuesto, la lectura y la escritura no se pueden realizar simultáneamente.

Los candados giratorios proporcionan una manera rápida y fácil de lograr esto. Si el tiempo de bloqueo no es largo y el código no se duerme, la mejor opción es utilizar un bloqueo de giro. Si el tiempo de bloqueo puede ser largo o es probable que el código se duerma mientras mantiene el bloqueo, es mejor usar el semáforo para completar la función de bloqueo.

Semáforos

Un semáforo en Linux es un tipo de bloqueo de suspensión. Si una tarea intenta adquirir un semáforo ya ocupado, el semáforo lo empuja en una cola de espera. Luego, déjelo dormir, entonces el procesador puede recuperar la libertad para ejecutar otro código, y cuando el proceso del semáforo libera el semáforo, la tarea en la cola de espera se activa y obtiene el semáforo.

1) Dado que el proceso de contención del semáforo se duerme mientras espera a que el bloqueo vuelva a estar disponible, el semáforo se aplica cuando el bloqueo se mantiene durante mucho tiempo, por el contrario, cuando el bloqueo se mantiene durante un breve período de tiempo El uso de semáforos no es muy adecuado. El costo de dormir, mantener la cola de espera y despertarse puede ser más largo que el tiempo total que la cerradura está ocupada.

2) Dado que el subproceso de ejecución está inactivo cuando el bloqueo está en contienda, el bloqueo de semáforo solo se puede obtener en el contexto del proceso porque no se puede programar en el contexto de interrupción. 3) Puedes ir a dormir mientras mantienes un semáforo, porque cuando otros procesos intentan obtener el mismo semáforo, no estarán bloqueados (porque el proceso simplemente se pone en suspensión y continuará ejecutándose).

4) No puedes tomar cerraduras de giro mientras estás tomando semáforos. Debido a que puede dormir mientras espera un semáforo, y no se le permite dormir mientras mantiene un bloqueo de giro.

5) El semáforo permite cualquier número de soportes de bloqueo al mismo tiempo, mientras que el bloqueo de giro permite que hasta una tarea lo retenga a la vez. La razón es que el semáforo tiene un valor de conteo, por ejemplo, el valor de conteo es 5, lo que significa que 5 hilos pueden acceder a la sección crítica al mismo tiempo. Si el valor inicial del semáforo comienza en 1, este semáforo es el semáforo mutuo (MUTEX). Para los semáforos de valor distinto de cero mayor que 1, también se puede denominar semáforo de conteo. Los semáforos utilizados por los conductores generales son semáforos mutuamente excluyentes.

El semáforo admite dos operaciones atómicas: Operaciones primitivas P /V (también llamadas operaciones hacia abajo y hacia arriba):

P: Si el valor del semáforo es mayor que 0, el semáforo se decrementa El valor del programa continúa ejecutándose, de lo contrario, el semáforo de espera de espera es mayor que cero.

V: El valor del semáforo de incremento. Si el valor del semáforo incrementado es mayor que 0, el proceso de espera se reactiva.

Hay dos versiones de la operación de bajada, que son interrumpibles para el sueño y el sueño sin interrupciones.

Semáforo de lectura-escritura

La relación entre los semáforos de lectura-escritura y los semáforos es similar a la relación entre los bloqueos de giro de lectura-escritura y los bloqueos de giro ordinarios.

Copyright © Conocimiento de Windows All Rights Reserved