2012-04-09 56 views
4

我继承像这样的代码:调用ResetEvent()时,我需要互斥锁吗?

m_mutex.Lock(); 
ResetEvent(m_hSyncObject); 
m_mutex.Unlock(); 

同为SetEvent()

在这种情况下必要的互斥体 - 做这些电话循规蹈矩或者我可以卸下锁脱身?这个函数已经有了一些我曾经提出过的原子的值,现在只是这些事件在锁定之内,所以如果可能的话,去掉它们将是一个很大的胜利。

+2

你不需要额外的互斥体 – 0xC0000022L 2012-04-09 16:18:10

回答

2

这个额外的互斥量几乎肯定是不需要的。 ResetEventSetEvent函数本身可以安全地从多个线程调用

鉴于此代码确实存在,编写该代码的开发人员很可能不明白他们创建的线程语义。我会视任何依赖于该逻辑的代码为高度可疑的。从长远来看,它可能为您节省一些时间,并预先审核线程问题的代码。

+1

已经遍布全球。 Profiler展示了大量的“快速”锁的调用。工作系统严重滥用。这是我不确定锁定的最后两个函数。现在,像你所说的那样,在代码中爬行,确保其他所有东西都应该是...... – 2012-04-09 16:25:49

+0

“事件探查器显示大量的”快速“锁的调用 - 哦,亲爱的:((我很同情。 – 2012-04-09 16:44:20

1

活动是原子的,所以没有必要使用一个互斥体SetEventResetEvent左右,除非有别的东西与它一起和两个必须自动完成的(例如,如果你设置一个事件和重置另一)。

+0

不是,没有那样的。设置和重置已经在单独的关键部分,但我会检查以确保它们不应该被锁定在一起。好的建议。 – 2012-04-09 16:28:59

1

警告程序员!

手动重置事件很难使用,可能需要您锁定设置和重置事件(自动重置事件可以更轻松地避免这些问题)。

考虑以下代码:

Worker() { 
    WaitForSingleObject(hEvent); 
    DoWork(); 
    ResetEvent(hEvent); 
} 

EventThread() { 
    QueueWork(); 
    SetEvent(hEvent); 
} 

有可能与活泼交织的工人的EventThread已经暗示它之后对事件复位,这将导致工人时,它会等待挂起。要在这种情况下正确使用手动重置事件,您需要获取重置事件的锁定,并通过重置事件来自动检查队列的状态。

自动重置事件让你自动唤醒并重置避免这场比赛的事件(如果你已经在工作进来时已经排队,但你不会错过任何醒来) 。