事件 (同步原語)

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

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

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

  • 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). 頁面存檔備份,存於互聯網檔案館