There are few new synchronization primitives has been introduced with Windows Vista like Condition Variables, Slim Reader/Writer Lock, One Time Initialization, Double Checked locking etc…
Let’s take a look to Condition variables
Condition variable is a user mode synchronization primitive to wait the thread(s) until a particular condition occurs. The conditional variable can be used with either Critical Section Objects and SRW Objects. We can either wake one or all threads waiting for condition variables according to our requirements. This type of synchronization mechanism can’t be shared among the multiple process as it’s user mode synchronization object. The following are the APIs used with Condition Variables.
| InitializeConditionVariable | Initializes a condition variable. |
| SleepConditionVariableCS | Sleeps on the specified condition variable and releases the specified critical section as an atomic operation. |
| SleepConditionVariableSRW | Sleeps on the specified condition variable and releases the specified SRW lock as an atomic operation. |
| WakeAllConditionVariable | Wakes all threads waiting on the specified condition variable. |
| WakeConditionVariable | Wakes a single thread waiting on the specified condition variable. |
OK Let’s take a simple sample provided from MSDN. We will be having a producer who should always write some data to a shared queue and we’re having a client reading data from the same queue.
// Producer
for (unsigned int i = 0;i < g_uiIterations;i++)
{
EnterCriticalSection(&g_csLock); // Produce work
g_listWork.push_back(i);
LeaveCriticalSection(&g_csLock);
WakeConditionVariable(&g_condNotEmpty);
Sleep(g_uiProducerDelay);
}
//Consumer
while (true)
{
EnterCriticalSection(&g_csLock);
while (g_listWork.empty())
{
SleepConditionVariableCS(&g_condNotEmpty,&g_csLock,INFINITE);
}
i = g_listWork.front();
g_listWork.pop_front();
LeaveCriticalSection(&g_csLock);
Sleep(g_uiConsumerDelay); // Simulating work
}
The above example is quite straight forward. It shows how we can sleep and wait using condition variables. The producer acquire the critical section for writing data in to queue. At this time the consumer thread will be waiting for the condition variables. When the producer calls “WakeConditionVariable”, the consumer thread will be release and sooner it will acquire the lock for critical section in the SleepConditionVariableCS call itself. After completing the usage of resource as usual we’ve to call LeaveCritical Section.
The synchronization object used here is Critical Section. Of course as part of initialization, The critical section object should be initialized using InitializeCriticalSection API and the Condition variable (CONDITION_VARIABLE) with InitializeConditionVariable API. If you notice, there are no API to clean up or destroy the CONDITION_VARIABLE structure as it’s not needed by the underlying implementation.
The above examples can be implemented in conventional style using event and critical section. The drawback of the method is, the event which we’re waiting will be a kernel object and it makes a costly kernel mode roundtrip for execution. While the condition variables are user mode synchronization objects.
You can see a sophisticated example in MSDN.

