Sección crítica

format_list_bulleted Contenido keyboard_arrow_down
ImprimirCitar

En la programación concurrente, los accesos concurrentes a recursos compartidos pueden provocar comportamientos inesperados o erróneos, por lo que las partes del programa donde se accede al recurso compartido deben protegerse de manera que eviten el acceso concurrente. Una forma de hacerlo se conoce como sección crítica o región crítica. A esta sección protegida no puede acceder más de un proceso o subproceso a la vez; otros quedan suspendidos hasta que el primero abandone la sección crítica. Normalmente, la sección crítica accede a un recurso compartido, como una estructura de datos, un dispositivo periférico o una conexión de red, que no funcionaría correctamente en el contexto de múltiples accesos simultáneos.

Necesidad de secciones críticas

Diferentes códigos o procesos pueden consistir en la misma variable u otros recursos que deben leerse o escribirse pero cuyos resultados dependen del orden en que ocurren las acciones. Por ejemplo, si el proceso A va a leer una variable x y el proceso B tiene que escribir en la misma variable x al mismo tiempo, el proceso A podría obtener el valor antiguo o nuevo de x.

Gráfico de flujo que representa la necesidad de sección crítica

Proceso A:

// Proceso A..b = x + 5; // instrucción ejecuta a tiempo = Tx.

Proceso B:

/ Proceso B..x = 3 + z; // instrucción ejecuta a tiempo = Tx.

En los casos en los que no se necesita un mecanismo de bloqueo con granularidad más fina, una sección crítica es importante. En el caso anterior, si A necesita leer el valor actualizado de x, es posible que ejecutar el proceso A y el proceso B al mismo tiempo no proporcione los resultados requeridos. Para evitar esto, la variable x está protegida por una sección crítica. Primero, B obtiene acceso a la sección. Una vez que B termina de escribir el valor, A obtiene acceso a la sección crítica y se puede leer la variable x.

Al controlar cuidadosamente qué variables se modifican dentro y fuera de la sección crítica, se evita el acceso simultáneo a la variable compartida. Una sección crítica generalmente se usa cuando un programa de subprocesos múltiples debe actualizar múltiples variables relacionadas sin que un subproceso separado realice cambios conflictivos en esos datos. En una situación relacionada, se puede utilizar una sección crítica para garantizar que solo un proceso a la vez pueda acceder a un recurso compartido, por ejemplo, una impresora.

Implementación de secciones críticas

La implementación de secciones críticas varía entre los diferentes sistemas operativos.

Una sección crítica normalmente terminará en un tiempo finito y un subproceso, tarea o proceso tendrá que esperar un tiempo fijo para ingresar a ella (espera limitada). Para asegurar el uso exclusivo de secciones críticas se requiere algún mecanismo de sincronización en la entrada y salida del programa.

La sección crítica es una parte de un programa que requiere exclusión mutua de acceso.

Cerraduras y secciones críticas en múltiples hilos

Como se muestra en la figura, en el caso de exclusión mutua (mutex), un subproceso bloquea una sección crítica mediante el uso de técnicas de bloqueo cuando necesita acceder al recurso compartido, y otros subprocesos tienen que esperar para tener su turno para ingresar. en la sección. Esto evita conflictos cuando dos o más subprocesos comparten el mismo espacio de memoria y desean acceder a un recurso común.

Pseudocode for implementing critical section

El método más sencillo para evitar cualquier cambio de control del procesador dentro de la sección crítica es implementar un semáforo. En sistemas monoprocesador, esto se puede hacer deshabilitando las interrupciones al ingresar a la sección crítica, evitando llamadas al sistema que puedan causar un cambio de contexto mientras se está dentro de la sección y restaurando las interrupciones a su estado anterior al salir. Cualquier subproceso de ejecución que ingrese a cualquier sección crítica en cualquier parte del sistema evitará, con esta implementación, que a cualquier otro subproceso, incluida una interrupción, se le otorgue tiempo de procesamiento en la CPU y, por lo tanto, que ingrese a cualquier otra sección crítica o, de hecho, a cualquier código. en absoluto, hasta que el hilo original abandone su sección crítica.

Este enfoque de fuerza bruta se puede mejorar mediante el uso de semáforos. Para entrar en una sección crítica, un hilo debe obtener un semáforo, que libera al salir de la sección. Se impide que otros subprocesos entren en la sección crítica al mismo tiempo que el subproceso original, pero son libres de obtener el control de la CPU y ejecutar otro código, incluidas otras secciones críticas que están protegidas por diferentes semáforos. El bloqueo de semáforo también tiene un límite de tiempo para evitar una condición de interbloqueo en la que un solo proceso adquiere un bloqueo durante un tiempo infinito, deteniendo los otros procesos que necesitan usar el recurso compartido protegido por la sección crítica.

Usos de las secciones críticas

Secciones críticas a nivel de kernel

Por lo general, las secciones críticas evitan la migración de subprocesos y procesos entre procesadores y la preferencia de procesos e subprocesos por interrupciones y otros procesos y subprocesos.

Las secciones críticas a menudo permiten el anidamiento. El anidamiento permite entrar y salir de múltiples secciones críticas a bajo costo.

Si el programador interrumpe el proceso o subproceso actual en una sección crítica, permitirá que el proceso o subproceso que se está ejecutando actualmente se ejecute hasta completar la sección crítica, o programará el proceso o subproceso para otro cuanto completo. El programador no migrará el proceso o subproceso a otro procesador y no programará la ejecución de otro proceso o subproceso mientras el proceso o subproceso actual se encuentre en una sección crítica.

De manera similar, si se produce una interrupción en una sección crítica, la información de la interrupción se registra para procesamiento futuro y la ejecución se devuelve al proceso o subproceso en la sección crítica. Una vez que se sale de la sección crítica y, en algunos casos, se completa el cuanto programado, se ejecutará la interrupción pendiente. El concepto de programación cuántica se aplica al sistema "por turnos" y políticas de programación similares.

Dado que las secciones críticas pueden ejecutarse solo en el procesador en el que se ingresan, la sincronización solo se requiere dentro del procesador en ejecución. Esto permite entrar y salir de secciones críticas a un costo casi nulo. No se requiere sincronización entre procesadores. Sólo se necesita sincronización del flujo de instrucciones. La mayoría de los procesadores proporcionan la cantidad necesaria de sincronización con el simple hecho de interrumpir el estado de ejecución actual. Esto permite que las secciones críticas en la mayoría de los casos no sean más que un recuento de secciones críticas ingresadas por procesador.

Las mejoras de rendimiento incluyen la ejecución de interrupciones pendientes a la salida de todas las secciones críticas y permitir que el programador se ejecute a la salida de todas las secciones críticas. Además, las interrupciones pendientes pueden transferirse a otros procesadores para su ejecución.

Las secciones críticas no deben usarse como primitivas de bloqueo duraderas. Las secciones críticas deben ser lo suficientemente breves para que se pueda ingresar, ejecutar y salir sin que se produzcan interrupciones por parte del hardware y el programador.

Las secciones críticas a nivel del kernel son la base del problema de bloqueo del software.

Secciones críticas en estructuras de datos

En la programación paralela, el código se divide en subprocesos. Las variables en conflicto de lectura y escritura se dividen entre subprocesos y cada subproceso tiene una copia de ellas. Las estructuras de datos como listas vinculadas, árboles, tablas hash, etc. tienen variables de datos que están vinculadas y no se pueden dividir entre subprocesos y, por lo tanto, implementar el paralelismo es muy difícil. Para mejorar la eficiencia de la implementación de estructuras de datos, es necesario ejecutar en paralelo múltiples operaciones como inserción, eliminación y búsqueda. Mientras se realizan estas operaciones, puede haber escenarios en los que un hilo busca el mismo elemento y otro lo elimina. En tales casos, la salida puede ser errónea. El hilo que busca el elemento puede tener un resultado, mientras que el otro hilo puede eliminarlo justo después de ese momento. Estos escenarios causarán problemas en la ejecución del programa al proporcionar datos falsos. Para evitar esto, un método es mantener toda la estructura de datos en la sección crítica para que solo se maneje una operación a la vez. Otro método es bloquear el nodo en uso en la sección crítica, para que otras operaciones no utilicen el mismo nodo. Por lo tanto, el uso de la sección crítica garantiza que el código proporcione los resultados esperados.

Secciones críticas en relación a los periféricos

Las secciones críticas también ocurren en el código que manipula periféricos externos, como dispositivos de E/S. Los registros de un periférico deben programarse con ciertos valores en una secuencia determinada; si dos o más procesos controlan un dispositivo simultáneamente, se producirá un comportamiento incorrecto: ninguno de los procesos tendrá el dispositivo en el estado que requiere.

Cuando se debe producir una unidad compleja de información en un dispositivo de salida mediante la emisión de múltiples operaciones de salida, se requiere acceso exclusivo para que otro proceso no corrompa el dato entrelazando sus propios bits de salida.

En la dirección de entrada, se requiere acceso exclusivo al leer un dato complejo a través de múltiples operaciones de entrada separadas, para evitar que otro proceso consuma algunas de las piezas, causando corrupción.

Los dispositivos de almacenamiento proporcionan una forma de memoria; El concepto de secciones críticas es igualmente relevante de la misma manera que lo es para las estructuras de datos compartidas en la memoria principal. Un proceso que realiza múltiples operaciones de acceso o actualización en un archivo está ejecutando una sección crítica que debe protegerse con un mecanismo de bloqueo de archivos adecuado.

Contenido relacionado

Proceso R

En astrofísica nuclear, el proceso rápido de captura de neutrones, también conocido como r-proceso, es un conjunto de reacciones nucleares que es...

Suma digital

Hay varios significados matemáticos comunes del término suma...

F Sharp (lenguaje de programación)

F# es un lenguaje de programación funcional primero, de propósito general, fuertemente tipado y multiparadigma que abarca funcionalidad, imperativo y...
Más resultados...
Tamaño del texto:
undoredo
format_boldformat_italicformat_underlinedstrikethrough_ssuperscriptsubscriptlink
save