簡體   English   中英

調用 ResetEvent() 時是否需要互斥或鎖定?

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

我繼承了一些這樣的代碼:

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

SetEvent()相同

在這種情況下是否需要這些 Mutexes - 這些調用會自行運行還是我可以移除鎖? 這個 function 已經有一些 inc/decs 值,我之前將它們設為原子,現在只有這些事件在鎖中,所以如果可能的話,擺脫它們將是一個巨大的勝利。

這個額外的互斥鎖幾乎肯定是不需要的。 ResetEventSetEvent函數本身可以安全地從多個線程調用

鑒於此代碼確實存在,編寫該代碼的開發人員似乎很可能不理解他們創建的線程語義。 我會高度懷疑任何依賴於該邏輯的代碼。 從長遠來看,它可能會為您節省一些時間提前到 go 並預先審核該代碼以解決線程問題

警告程序員!

手動重置事件很難使用,可能需要您鎖定事件的設置和重置(自動重置事件可以更輕松地避免這些問題)。

考慮這段代碼:

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

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

在 EventThread 發出信號,worker 可以通過 racy interleaving 重置事件,這將導致 worker 在等待時掛起。 在這種情況下,要正確使用手動重置事件,您需要獲取重置事件周圍的鎖,並通過重置事件自動檢查隊列的 state。

自動重置事件讓您自動喚醒並重置避免這場競爭的事件(如果您在工作進入時已經排空隊列,您可能會額外喚醒一次,但您不會錯過任何喚醒)。

事件是原子的,所以不需要在SetEventResetEvent周圍使用互斥量,除非有其他東西伴隨它並且兩者必須以原子方式完成(例如,如果您設置一個事件並重置另一個事件)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM