我继承了这样的代码:
m_mutex.Lock();
ResetEvent( m_hSyncObject );
m_mutex.Unlock();
SetEvent()
在这种情况下,这些互斥锁是否必要 - 这些调用是自己行动还是我可以逃脱锁定?这个函数已经有了一些我早先生成的值的inc / decs,现在只是这些事件都在锁中,所以如果可能的话,摆脱它们将是一个很大的胜利。
答案 0 :(得分:3)
这个额外的互斥锁几乎肯定是不需要的。 ResetEvent
和SetEvent
函数本身可以安全地从多个线程调用
鉴于此代码确实存在,编写该代码的开发人员很可能不了解他们创建的线程语义。我会根据这种逻辑对任何代码进行高度怀疑。从长远来看,它可能会为您节省一些时间,以便预先审核线程问题的代码
答案 1 :(得分:2)
警告程序员!
手动重置事件很难使用,可能需要您锁定设置和重置事件(自动重置事件可以更轻松地避免这些问题)。
考虑以下代码:
Worker() {
WaitForSingleObject(hEvent);
DoWork();
ResetEvent(hEvent);
}
EventThread() {
QueueWork();
SetEvent(hEvent);
}
在事件传递已发出信号后,工作人员可以通过racy interleaving重置事件,这会导致工作人员在等待时挂起。要在这种情况下正确使用手动重置事件,您需要获取重置事件周围的锁定,并通过重置事件来原子检查队列状态。
自动重置事件让你以原子方式唤醒并重置事件,避免这种竞争(如果你在工作进入时已经排空了队列,你可能会多醒一次,但你不会错过任何一次醒来)。
答案 2 :(得分:1)
事件是原子的,因此不需要在SetEvent
或ResetEvent
,周围使用互斥锁,除非还有其他内容,而且必须完成这两项操作原子地(例如,如果你设置一个事件并重置另一个事件)。