以下是我对SleepConditionVariableCS
,WakeAllConditionVariable
的实现以及线程创建函数。问题是,有时当我尝试创建一个线程时,创建线程会卡在WaitForSingleObject( cv->mut, INFINITE );
的{{1}}上。我无法弄清楚这里的竞争条件是什么。
SleepConditionVariableCS
答案 0 :(得分:1)
在尝试使用win32 apis实现pthread样式的条件变量时,请查看以下非常详细的陷阱分析。 http://www.cs.wustl.edu/~schmidt/win32-cv-1.html。 (特别是第3.4节)。
在您的代码中,我目前只看到一个问题。在SleepConditionVariableCS()
:
LeaveCriticalSection (cs);
if (SignalObjectAndWait(cv->mut, cv->sema_, dwMilliseconds, FALSE) == WAIT_TIMEOUT){ //SignalObjectAndWait releases the lock
// RIGHT HERE YOU HAVE NOT ACQUIRED cv->mut
cv->waiters_count--; // SO THIS IS A DATA RACE (with the cv->waiters_count uses in WakeAllConditionVariable()
}
答案 1 :(得分:0)
我认为没有任何真正突出的逻辑缺陷。
...然而
在使用之前,您是否将CONDITION_VARIABLE初始化为已知状态?
您不会检查几个系统调用的返回值,这些调用可能会返回您永远不会看到的错误。 WaitForSingleObject
和EnterCriticalSection
可以失败或处理不当。
在处理条件变量时,您是否始终锁定thread->lock
并将其锁定?我看到两段不同的代码,引用了thread->lock
。
每次都以相同的顺序锁定/解锁关键部分和sems吗?