Variables de condición
Las variables de condición son primitivas de sincronización que permiten que los subprocesos esperen hasta que se produzca una condición determinada. Las variables de condición son objetos en modo de usuario que no se pueden compartir entre procesos.
Las variables de condición permiten a los subprocesos liberar de forma atómica un bloqueo y entrar en el estado de suspensión. Se pueden usar con secciones críticas o bloqueos ligeros de lector/escritor (SRW). Las variables de condición admiten operaciones que "reactivan uno" o "reactivan todos" subprocesos en espera. Después de reactivar un subproceso, vuelve a adquirir el bloqueo que liberó cuando el subproceso entró en estado de suspensión.
Tenga en cuenta que el autor de la llamada debe asignar una estructura de CONDITION_VARIABLE e inicializarla llamando a InitializeConditionVariable (para inicializar la estructura dinámicamente) o asignar la constante CONDITION_VARIABLE_INIT a la variable de estructura (para inicializar la estructura estáticamente).
Windows Server 2003 y Windows XP: No se admiten variables de condición.
A continuación se muestran las funciones de la variable de condición.
Función de variable de condición | Descripción |
---|---|
InitializeConditionVariable | Inicializa una variable de condición. |
SleepConditionVariableCS | Se suspende en la variable de condición especificada y libera la sección crítica especificada como una operación atómica. |
SleepConditionVariableSRW | Se suspende en la variable de condición especificada y libera el bloqueo SRW especificado como una operación atómica. |
WakeAllConditionVariable | Activa todos los subprocesos en espera de la variable de condición especificada. |
WakeConditionVariable | Activa un único subproceso en espera de la variable de condición especificada. |
El pseudocódigo siguiente muestra el patrón de uso típico de las variables de condición.
CRITICAL_SECTION CritSection;
CONDITION_VARIABLE ConditionVar;
void PerformOperationOnSharedData()
{
EnterCriticalSection(&CritSection);
// Wait until the predicate is TRUE
while( TestPredicate() == FALSE )
{
SleepConditionVariableCS(&ConditionVar, &CritSection, INFINITE);
}
// The data can be changed safely because we own the critical
// section and the predicate is TRUE
ChangeSharedData();
LeaveCriticalSection(&CritSection);
// If necessary, signal the condition variable by calling
// WakeConditionVariable or WakeAllConditionVariable so other
// threads can wake
}
Por ejemplo, en una implementación de un bloqueo lector/escritor, la TestPredicate
función comprobaría que la solicitud de bloqueo actual es compatible con los propietarios existentes. Si es así, adquiera el bloqueo; de lo contrario, duerme. Para obtener un ejemplo más detallado, consulte Uso de variables de condición.
Las variables de condición están sujetas a reactivaciones falsas (las que no están asociadas a una reactivación explícita) y las reactivaciones robadas (otro subproceso administra la ejecución antes del subproceso despertado). Por lo tanto, debe volver a comprobar un predicado (normalmente en un bucle while) después de que se devuelva una operación de suspensión.
Puede reactivar otros subprocesos mediante WakeConditionVariable o WakeAllConditionVariable dentro o fuera del bloqueo asociado a la variable de condición. Normalmente es mejor liberar el bloqueo antes de despertar otros subprocesos para reducir el número de modificadores de contexto.
A menudo es conveniente usar más de una variable de condición con el mismo bloqueo. Por ejemplo, una implementación de un bloqueo de lector/escritor podría usar una sola sección crítica, pero variables de condición independientes para lectores y escritores.
Temas relacionados