stringtranslate.com

Sección crítica

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 se evite 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. [1]

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 debe 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 una sección crítica

Proceso A:

// Proceso A. . segundo = x + 5 ; // la instrucción se ejecuta en el momento = Tx .     

Proceso B:

// Proceso B. . x = 3 + z ; // la instrucción se ejecuta en el momento = 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 , ejecutar el proceso A y el proceso B al mismo tiempo puede no dar 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 generalmente terminará en un tiempo finito, [2] y un hilo, 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.

Bloqueos y secciones críticas en múltiples hilos.

Como se muestra en la figura, [3] 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 hasta 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. [2]

Pseudocódigo para implementar la sección crítica.

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

Normalmente, las secciones críticas impiden la migración de subprocesos y procesos entre procesadores y la preferencia de procesos e subprocesos por interrupciones y otros procesos e 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 ocurre 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. [4] 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 a las políticas de programación " round-robin " y similares .

Dado que las secciones críticas pueden ejecutarse sólo en el procesador en el que se ingresan, la sincronización sólo 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 [5] . 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 primitivo de bloqueo duradero. 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 de 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. [6] Para mejorar la eficiencia de la implementación de estructuras de datos, se deben ejecutar múltiples operaciones como inserción, eliminación y búsqueda en paralelo. 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. [6]

Apartados críticos 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 y provoque 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.

Ver también

Referencias

  1. ^ Raynal, Michel (2012). Programación concurrente: algoritmos, principios y fundamentos . Medios de ciencia y negocios de Springer. pag. 9.ISBN _ 978-3642320279.
  2. ^ ab Jones, M. Tim (2008). Programación de aplicaciones GNU/Linux (2ª ed.). [Hingham, Massachusetts] Charles River Media. pag. 264.ISBN _ 978-1-58450-568-6.
  3. ^ Chen, Stenstrom, Guancheng, Per (10 al 16 de noviembre de 2012). "Análisis de bloqueos críticos: diagnóstico de cuellos de botella de secciones críticas en aplicaciones multiproceso". Conferencia internacional de 2012 sobre informática, redes, almacenamiento y análisis de alto rendimiento . págs. 1–11. doi :10.1109/sc.2012.40. ISBN 978-1-4673-0805-2. S2CID  12519578.{{cite book}}: Mantenimiento CS1: varios nombres: lista de autores ( enlace )
  4. ^ "TRABAJO DE INVESTIGACIÓN SOBRE LA SOLUCIÓN DE SOFTWARE DEL PROBLEMA DE LA SECCIÓN CRÍTICA". Revista Internacional de Investigación en Ingeniería y Tecnología Avanzada (IJATER) . 1 . Noviembre de 2011.
  5. ^ Dubois, Scheurich, Michel, Christoph (1988). "Sincronización, coherencia y ordenación de eventos en multiprocesadores". Serie de encuestas y tutoriales . 21 (2): 9–21. doi :10.1109/2.15. S2CID  1749330.{{cite journal}}: Mantenimiento CS1: varios nombres: lista de autores ( enlace )
  6. ^ ab Solihin, Yan (17 de noviembre de 2015). Fundamentos de la arquitectura multinúcleo paralelo . Taylor y Francisco. ISBN 9781482211184.

enlaces externos