Objetos de sección crítica

Un objeto de sección crítica proporciona sincronización similar a la proporcionada por un objeto de exclusión mutua, salvo que solo los subprocesos de un único proceso pueden usar una sección crítica. Los objetos de sección críticos no se pueden compartir entre procesos.

Los objetos event, mutex y semaphore también se pueden usar en una aplicación de proceso único, pero los objetos de sección críticos proporcionan un mecanismo ligeramente más rápido y eficaz para la sincronización de exclusión mutua (una instrucción de prueba y conjunto específica del procesador). Al igual que un objeto de exclusión mutua, un objeto de sección crítico solo puede ser propiedad de un subproceso a la vez, lo que hace que sea útil para proteger un recurso compartido frente al acceso simultáneo. A diferencia de un objeto de exclusión mutua, no hay forma de saber si se ha abandonado una sección crítica.

A partir de Windows Server 2003 con Service Pack 1 (SP1), los subprocesos que esperan en una sección crítica no adquieren la sección crítica por primera vez, primero sirven. Este cambio aumenta significativamente el rendimiento para la mayoría del código. Sin embargo, algunas aplicaciones dependen del orden primero en salir (FIFO) y pueden funcionar mal o no en las versiones actuales de Windows (por ejemplo, las aplicaciones que han estado usando secciones críticas como un limitador de velocidad). Para asegurarse de que el código sigue funcionando correctamente, es posible que tenga que agregar un nivel adicional de sincronización. Por ejemplo, supongamos que tiene un subproceso de productor y un subproceso de consumidor que usan un objeto de sección crítico para sincronizar su trabajo. Cree dos objetos de evento, uno para cada subproceso que se usará para indicar que está listo para que el otro subproceso continúe. El subproceso de consumidor esperará a que el productor indique su evento antes de entrar en la sección crítica y el subproceso del productor esperará a que el subproceso del consumidor indique su evento antes de entrar en la sección crítica. Después de que cada subproceso deje la sección crítica, señala su evento para liberar el otro subproceso.

Windows Server 2003 y Windows XP: Los subprocesos que están esperando una sección crítica se agregan a una cola de espera; se reactivan y, por lo general, adquieren la sección crítica en el orden en que se agregaron a la cola. Sin embargo, si los subprocesos se agregan a esta cola a una velocidad lo suficientemente rápida, el rendimiento se puede degradar debido al tiempo que se tarda en despertar cada subproceso en espera.

El proceso es responsable de asignar la memoria utilizada por una sección crítica. Normalmente, esto se hace simplemente declarando una variable de tipo CRITICAL_SECTION. Antes de que los subprocesos del proceso puedan usarlo, inicialice la sección crítica mediante la función InitializeCriticalSection o InitializeCriticalSectionAndSpinCount .

Un subproceso usa la función EnterCriticalSection o TryEnterCriticalSection para solicitar la propiedad de una sección crítica. Usa la función LeaveCriticalSection para liberar la propiedad de una sección crítica. Si el objeto de sección crítica pertenece actualmente a otro subproceso, EnterCriticalSection espera indefinidamente la propiedad. Por el contrario, cuando se usa un objeto de exclusión mutua, las funciones de espera aceptan un intervalo de tiempo de espera especificado. La función TryEnterCriticalSection intenta escribir una sección crítica sin bloquear el subproceso que llama.

Cuando un subproceso posee una sección crítica, puede realizar llamadas adicionales a EnterCriticalSection o TryEnterCriticalSection sin bloquear su ejecución. Esto evita que un subproceso se interbloquee mientras espera una sección crítica que ya posee. Para liberar su propiedad, el subproceso debe llamar a LeaveCriticalSection una vez por cada vez que escribió la sección crítica. No hay ninguna garantía sobre el orden en el que los subprocesos en espera adquirirán la propiedad de la sección crítica.

Un subproceso usa la función InitializeCriticalSectionAndSpinCount o SetCriticalSectionSpinCount para especificar un número de giros para el objeto de sección crítica. Girar significa que cuando un subproceso intenta adquirir una sección crítica bloqueada, el subproceso entra en un bucle, comprueba si se libera el bloqueo y, si el bloqueo no se libera, el subproceso entra en suspensión. En los sistemas de procesador único, se omite el número de giros y el número de giros de sección crítica se establece en 0 (cero). En los sistemas multiprocesador, si la sección crítica no está disponible, el subproceso que realiza la llamada gira los tiempos dwSpinCount antes de realizar una operación de espera en un semáforo asociado a la sección crítica. Si la sección crítica se libera durante la operación de giro, el subproceso que llama evita la operación de espera.

Cualquier subproceso del proceso puede usar la función DeleteCriticalSection para liberar los recursos del sistema que se asignan cuando se inicializa el objeto de sección crítico. Después de llamar a esta función, no se puede usar el objeto de sección crítica para la sincronización.

Cuando un objeto de sección crítica es propiedad, los únicos subprocesos afectados son los subprocesos que están esperando la propiedad en una llamada a EnterCriticalSection. Los subprocesos que no están esperando pueden continuar ejecutándose.

Objetos de exclusión mutua

Uso de objetos de sección críticos