Condition Variable

← Back to Synchronization

Overview

A condition variable provides a way for one or more threads to wait until they are notified that a condition has changed. It works together with a CRITICAL_SECTION or SYNCHRONIZE object to allow safe synchronization of shared data.

Syntax

BOOL InitializeConditionVariable(
    PCONDITION_VARIABLE ConditionVariable
);

VOID SleepConditionVariableCS(
    PCONDITION_VARIABLE ConditionVariable,
    PCRITICAL_SECTION CriticalSection,
    DWORD dwMilliseconds
);

VOID WakeConditionVariable(
    PCONDITION_VARIABLE ConditionVariable
);

VOID WakeAllConditionVariable(
    PCONDITION_VARIABLE ConditionVariable
);

Parameters

FunctionParameterDescription
InitializeConditionVariableConditionVariablePointer to a CONDITION_VARIABLE structure to be initialized.
SleepConditionVariableCSConditionVariablePointer to the condition variable to wait on.
CriticalSectionPointer to the critical section that must be locked before calling.
dwMillisecondsTimeout in milliseconds. Use INFINITE for no timeout.
WakeConditionVariableConditionVariablePointer to the condition variable to wake a single waiting thread.
WakeAllConditionVariableConditionVariablePointer to the condition variable to wake all waiting threads.

Remarks

Example

Producer–consumer example using a condition variable.

#include <windows.h>
#include <stdio.h>

#define BUFFER_SIZE 5

int buffer[BUFFER_SIZE];
int count = 0;
CONDITION_VARIABLE cv;
CRITICAL_SECTION cs;

DWORD WINAPI Producer(LPVOID param) {
    for (int i = 0; i < 20; ++i) {
        EnterCriticalSection(&cs);
        while (count == BUFFER_SIZE) {
            SleepConditionVariableCS(&cv, &cs, INFINITE);
        }
        buffer[count++] = i;
        printf("Produced: %d\n", i);
        WakeConditionVariable(&cv);
        LeaveCriticalSection(&cs);
        Sleep(100);
    }
    return 0;
}

DWORD WINAPI Consumer(LPVOID param) {
    for (int i = 0; i < 20; ++i) {
        EnterCriticalSection(&cs);
        while (count == 0) {
            SleepConditionVariableCS(&cv, &cs, INFINITE);
        }
        int value = buffer[--count];
        printf("Consumed: %d\n", value);
        WakeConditionVariable(&cv);
        LeaveCriticalSection(&cs);
        Sleep(150);
    }
    return 0;
}

int main() {
    InitializeConditionVariable(&cv);
    InitializeCriticalSection(&cs);

    HANDLE hProd = CreateThread(NULL,0,Producer,NULL,0,NULL);
    HANDLE hCons = CreateThread(NULL,0,Consumer,NULL,0,NULL);

    WaitForSingleObject(hProd, INFINITE);
    WaitForSingleObject(hCons, INFINITE);

    DeleteCriticalSection(&cs);
    return 0;
}