Windows条件变量与事件

Y.Z*_*Y.Z 6 c windows multithreading condition-variable readerwriterlockslim

我们可以使用新的条件变量原语或windows事件来同步WinNT v6.x或更高版本中的线程.考虑以下两种方法,我们希望工作者在main中设置"go"的同时运行,否则它们都应该阻塞.

/*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);
}
Run Code Online (Sandbox Code Playgroud)

要么

/*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);
}
Run Code Online (Sandbox Code Playgroud)

在第一种方法,工人封锁SleepConditionVariableSRW和醒来WakeAllConditionVariable.在第二个中,它们在WaitForSingleObject上被阻塞并被SetEvent唤醒.

哪一个在实践中更好,只考虑开销?(提示:上下文切换,锁争用,阻塞线程的开销)

我会选择第一个但感觉缺乏理由.

Ant*_*ams 5

这个特殊用例非常适合事件:它是一次性过程,必须唤醒所有等待的线程.

条件变量更适合于队列之类的东西,其中有一个关联的谓词在等待线程唤醒时可能与否(例如队列中的项目 - 它们可能已被另一个线程使用),或者重要的是线程唤醒是通知条件变量时已经等待的线程之一,而不是之后出现的线程.

另外,正如Hans所指出的,Windows本机条件变量仅适用于Vista或更高版本,因此如果与Windows XP的兼容性受到关注,则无法使用它们.