cwindowsmultithreadingcondition-variablereaderwriterlockslim

Windows Condition Variable vs. Event


We can use either the new condition variable primitive or windows event in order to synchronize threads in WinNT v6.x or later. Consider the following two approaches, we want workers to run at the same time when "go" is set in main, otherwise they should all block.

/*language C code*/
/*Windows Condition Variable*/
int go=0;
CONDITION_VARIABLE cv;
SRWLOCK lock;
void workers()
{
    AcquireSRWLockShared(&lock);
    if(go==0)
    {
        SleepConditionVariableSRW(&cv, &lock, INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED);
    }
    ReleaseSRWLockShared(&lock);
    /*
    Workers continue...
    */
}
void main()
{
    int i;
    InitializeConditionVariable(&cv);
    InitializeSRWLock(&lock);
    for(i=0;i<10;i++)
    {
        CreateThread(0, 0, workers, 0, 0, 0);
    }
    AcquireSRWLockExclusive(&lock);
    go=1;
    ReleaseSRWLockExclusive(&lock);
    WakeAllConditionVariable(&cv);
}

or

/*language C code*/
/*Windows Event*/
HANDLE go;
void workers()
{
    WaitForSingleObject(go, INFINITE);
    /*
    Workers continue...
    */
}
void main()
{
    int i;
    go=CreateEvent(0,1,0,0); /*No security descriptor, Manual Reset, initially 0, no name*/
    for(i=0;i<10;i++)
    {
        CreateThread(0, 0, workers, 0, 0, 0);
    }
    SetEvent(go);
}

In the first approach, workers are blocked on SleepConditionVariableSRW and woke up by WakeAllConditionVariable. In the second, they are blocked on WaitForSingleObject and woke up by SetEvent.

Which one is better in practice, only regarding overhead? (hint: context switch, lock contention, overhead of blocking threads)

I would choose the first but feel lack of justification.


Solution

  • This particular use case is ideal for an event: it's a one-shot process, where all waiting threads must be woken.

    Condition variables are better suited for things like queues, where there is an associated predicate that may or not be true when the waiting thread wakes up (such as items on the queue --- they may have been consumed by another thread), or where it matters that the thread woken is one of those already waiting when the condition variable is notified, rather than one that comes along afterwards.

    Plus, as Hans pointed out, Windows native condition variables only work on Vista or later, so you can't use them if compatibility with Windows XP is a concern.