c - Windows 条件变量与事件

标签 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);
}

/*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);
}

在第一种方法中,worker 在 SleepConditionVariableSRW 上被阻塞,并被 WakeAllConditionVariable 唤醒。在第二个中,它们在 WaitForSingleObject 上被阻止并被 SetEvent 唤醒。

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

我会选择第一个,但觉得缺乏理由。

最佳答案

这个特定的用例非常适合事件:它是一个一次性进程,所有等待的线程都必须被唤醒。

条件变量更适合队列之类的东西,其中有一个关联的谓词,当等待线程唤醒时可能为真也可能不为真(例如队列中的项目——它们可能已被另一个线程消耗) ,或者重要的是,当条件变量被通知时,唤醒的线程是已经在等待的线程之一,而不是随后出现的线程。

此外,正如 Hans 指出的那样,Windows native 条件变量仅适用于 Vista 或更高版本,因此如果担心与 Windows XP 的兼容性,则不能使用它们。

关于c - Windows 条件变量与事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5233681/

相关文章:

c++ - 使用矩阵到 PMG 的棋盘

c - 在 C 中,为什么我的clearList函数不起作用

c++ - Boost 文件系统总是在 Windows 上返回 false

windows - 如何在 Windows 7 Aero 任务预览中创建自己的控件?

c++ - 线程在 while 循环中间随机停止

c - 调用方法时如何在 C 中使用类似名称的类

c - c中的win32线程

windows - 如何从批处理文件中持久设置 Windows 7 中的变量?

c# - 如何使用委托(delegate)在线程包装器类中传递方法?

Java SWT 和无效的线程访问