事件 (同步原語)

计算机科学中的一种同步机制

事件作為一種同步原語,是計算機科學中的一種同步機制,用來指示等待中的進程特定條件已經變為真。

事件對象一般具有下述操作:

  • wait - 執行中的線程被掛起直到事件為真。如果執行wait時事件已為真,則空操作。
  • set - 設置事件狀態為真,所有等待此事件的進程變為可調度。
  • clear - 設置事件狀態為假。

事件類似於管程中的條件變量。

Windows系統

Microsoft Windows操作系統提供的事件內核對象,狀態為signaled對應於狀態為真;使用WaitForObject及相關系統函數實現wait操作,SetEvent系統函數實現set操作,ResetEvent系統函數實現clear操作。

在創建事件對象時可以設置為「自動重置事件」或「手動重置事件」。當一個手動重置事件被觸發的時候,正在等待該事件的所有線程都將變成可調度狀態;而當一個自動重置事件對象被觸發的時候,只有一個正在等待該事件的線程會變成可調度狀態,隨後該事件對象自動變為未觸發態,但是如果被觸發時沒有等待該事件對象的線程,那麼該事件對象會保持觸發狀態,直至遇到第一個等待該事件對象的線程。

Windows API還有一個函數PulseEvent,會把一個正在等待該事件對象的線程變成可調度狀態,事件對象隨即保持未觸發狀態;如果函數調用時沒有等待該事件對象的線程那麼等效於什麼都不做。可見,PulseEvent並不等價於觸發自動重置事件對象。MSDN已經指出不要使用PulseEvent,[1]因為無法保證一個正在等待該事件對象的線程一定會被喚醒,其根源是掛起的線程可被系統調度執行內核級異步過程調用,這種事無法預測也無法察覺,此時發生PulseEvent就無法喚醒這個正在執行內核級異步過程調用的線程。

C++語言標準

C++語言標準已經實現了這種並發編程的同步事件。在C++11STL中增加了futurepromise兩種類模板,分別表示同步事件的消費者與生產者。

參考文獻

  1. ^ PulseEvent function in MSDN: "Therefore, PulseEvent is unreliable and should not be used by new applications.". [2017-09-04]. (原始內容存檔於2017-09-04). 頁面存檔備份,存於網際網路檔案館