Windows Vista Synchronization: Condition Variables

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.

Technorati Tags: ,

Sharing my thoughts...

Leave a Reply

 

 

 

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

blog comments powered by Disqus