4

我继承了一些这样的代码:

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

相同的SetEvent()

在这种情况下,这些互斥锁是必需的吗?这些调用是否会表现自己,或者我可以摆脱锁吗?这个函数已经有一些我之前原子化的值 inc/decs,现在这些事件都在锁中,所以如果可能的话,摆脱它们将是一个巨大的胜利。

4

3 回答 3

3

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

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

于 2012-04-09T16:19:54.250 回答
2

警告程序员!

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

考虑这段代码:

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

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

在 EventThread 发出信号后,worker 可能会通过 racy interleaving 重置事件,这将导致 worker 在等待时挂起。要在这种情况下正确使用手动重置事件,您需要获取重置事件周围的锁,并通过重置事件原子地检查队列的状态。

自动重置事件让您自动唤醒并重置避免这场比赛的事件(如果您在工作进入时已经排空队列,您可能会额外唤醒一次,但您不会错过任何唤醒)。

于 2012-05-06T17:30:06.517 回答
1

Events are atomic, so there's no need to use a mutex around a SetEvent or ResetEvent, unless there's something else along with it and the two have to be done atomically (e.g., if you set one event and reset another).

于 2012-04-09T16:19:40.767 回答