Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 668
Y.Z Avatar asked Mar 08 '11 14:03

Y.Z


People also ask

When would you want to use a condition variable?

Condition variables are used to wait until a particular condition predicate becomes true. This condition predicate is set by another thread, usually the one that signals the condition.

What's the difference between mutex and condition variable?

While mutex implement synchronization by controlling thread access to data, condition variables allow threads to synchronize based upon the actual value of data. Without condition variables, the programmer would need to have threads continually polling (possibly in a critical section), to check if the condition is met.

What are the two types of actions taken by a condition variable?

There are two types of actions that can be performed with condition variables: wait. signal.


2 Answers

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.

like image 127
Anthony Williams Avatar answered Oct 19 '22 17:10

Anthony Williams


Support for condition variables requires Vista or better. That's usually where the buck stops, supporting XP unfortunately tends to be still important. Your second snippet also does has the considerable advantage that it is trivial to understand. I don't have a clue what you're trying to do in the first one, it looks wrong.

like image 35
Hans Passant Avatar answered Oct 19 '22 16:10

Hans Passant