简体   繁体   English

调用 ResetEvent() 时是否需要互斥或锁定?

[英]Do I need to mutex or lock when calling ResetEvent()?

I've inherited some code like this:我继承了一些这样的代码:

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

Same for SetEvent()SetEvent()相同

Are those Mutexes necessary in this case - do those calls behave themselves or can I get away with removing the locks?在这种情况下是否需要这些 Mutexes - 这些调用会自行运行还是我可以移除锁? This function has already had some inc/decs of values that I made atomic earlier and now just these events are within the locks, so getting rid of them would be a big win if possible.这个 function 已经有一些 inc/decs 值,我之前将它们设为原子,现在只有这些事件在锁中,所以如果可能的话,摆脱它们将是一个巨大的胜利。

This extra mutex is almost certainly unneeded.这个额外的互斥锁几乎肯定是不需要的。 The ResetEvent and SetEvent functions themselves are safe to call from multiple threads ResetEventSetEvent函数本身可以安全地从多个线程调用

Given that this code does exists it seems highly likely that the developer who wrote that code didn't understand the threading semantics they'd created.鉴于此代码确实存在,编写该代码的开发人员似乎很可能不理解他们创建的线程语义。 I would treat any code depending on that logic as highly suspect.我会高度怀疑任何依赖于该逻辑的代码。 It'd probably save you some time in the long run to go ahead and pre-audit that code for threading issues从长远来看,它可能会为您节省一些时间提前到 go 并预先审核该代码以解决线程问题

Caveat programmer!警告程序员!

Manual-reset events are hard to use and may require you to hold a lock around setting and resetting the event (auto-reset events make it easier to avoid these issues).手动重置事件很难使用,可能需要您锁定事件的设置和重置(自动重置事件可以更轻松地避免这些问题)。

Consider this code:考虑这段代码:

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

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

It is possible with racy interleaving for the worker to reset the event after the EventThread has signalled it, which will cause the worker to hang when it waits.在 EventThread 发出信号,worker 可以通过 racy interleaving 重置事件,这将导致 worker 在等待时挂起。 To use the manual-reset event properly in this case you'd need to acquire a lock around the reset event and check the state of the queue atomically with resetting the event.在这种情况下,要正确使用手动重置事件,您需要获取重置事件周围的锁,并通过重置事件自动检查队列的 state。

Auto-reset events let you atomically wake up and reset the event which avoids this race (you might wake up one extra time if you already were draining the queue when work came in, but you won't miss any wakes).自动重置事件让您自动唤醒并重置避免这场竞争的事件(如果您在工作进入时已经排空队列,您可能会额外唤醒一次,但您不会错过任何唤醒)。

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 (eg, if you set one event and reset another).事件是原子的,所以不需要在SetEventResetEvent周围使用互斥量,除非有其他东西伴随它并且两者必须以原子方式完成(例如,如果您设置一个事件并重置另一个事件)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM