重要區段物件
重要區段物件 提供類似 Mutex 物件所提供的同步處理,不同之處在於關鍵區段只能由單一進程的線程使用。 重要區段對象無法跨進程共用。
事件、Mutex 和號誌物件也可以在單一進程應用程式中使用,但關鍵區段物件提供稍微快一點、更有效率的機制來進行相互排除同步處理(處理器特定的測試和設定指令)。 就像 Mutex 物件一樣,重要區段物件一次只能由一個線程擁有,這讓保護共用資源免於同時存取很有用。 與 Mutex 物件不同,無法判斷重要區段是否已放棄。
從 Windows Server 2003 Service Pack 1 (SP1) 開始,在關鍵區段等候的線程不會以第一個先出先出的第一個服務為基礎取得關鍵區段。 這項變更可大幅提升大部分程式代碼的效能。 不過,某些應用程式相依於先出先出(FIFO)排序,而且在目前版本的 Windows 上可能執行效能不佳或根本沒有效能(例如,已使用重要區段作為速率限制器的應用程式)。 若要確保您的程式代碼繼續正常運作,您可能需要新增額外的同步處理層級。 例如,假設您有生產者線程和取用者線程,而該線程使用重要區段對象來同步處理其工作。 建立兩個事件物件,每個線程各一個,用來表示它已準備好讓另一個線程繼續進行。 取用者線程會等候產生者在進入關鍵區段之前發出事件訊號,而產生者線程會等候取用者線程在進入關鍵區段之前發出事件訊號。 在每個線程離開關鍵區段之後,它會發出其事件以釋放另一個線程的訊號。
Windows Server 2003 和 Windows XP: 等候重要區段的線程會新增至等候佇列;它們已覺醒,且通常會依照新增至佇列的順序取得關鍵區段。 不過,如果線程以足夠快的速度新增至此佇列,效能可能會因為喚醒每個等候線程所需的時間而降低。
此程式負責配置重要區段所使用的記憶體。 一般而言,只要宣告類型為 CRITICAL_SECTION的變數,即可完成此作業。 進程線程可以使用之前,請先使用 initializeCriticalSectionInitializeCriticalSection 或 InitializeCriticalSectionAndSpinCount 函式來初始化關鍵區段。
線程會使用 EnterCriticalSection 或 TryEnterCriticalSection 函式來要求重要區段的擁有權。 它會使用 LeaveCriticalSection 函式來釋放重要區段的擁有權。 如果關鍵區段物件目前由另一個線程擁有,EnterCriticalSection 無限期等候擁有權。 相反地,當 mutex 物件用於相互排除時,等候函式 接受指定的超時時間間隔。 TryEnterCriticalSection 函式會嘗試進入重要區段,而不會封鎖呼叫線程。
當線程擁有重要區段時,它可以對 EnterCriticalSection 或 TryEnterCriticalSection 進行其他呼叫,而不會封鎖其執行。 這可防止線程在等候已擁有的重要區段時自行死結。 若要釋放其擁有權,線程必須在每次進入關鍵區段時呼叫 LeaveCriticalSection 一次。 無法保證等候線程取得重要區段擁有權的順序。
線程會使用 InitializeCriticalSectionAndSpinCount 或 SetCriticalSectionSpinCount 函式來指定關鍵區段物件的微調計數。 旋轉表示當線程嘗試取得鎖定的重要區段時,線程會進入迴圈,檢查是否已釋放鎖定,如果鎖定未釋放,線程就會進入睡眠狀態。 在單處理器系統上,會忽略微調計數,而關鍵區段微調計數會設定為0(零)。 在多處理器系統上,如果重要區段無法使用,呼叫端線程會在與關鍵區段相關聯的旗號上執行等候作業之前,先 dwSpinCount 次。 如果關鍵區段在微調作業期間變成可用,則呼叫線程會避免等候作業。
進程的任何線程都可以使用 DeleteCriticalSection 函式來釋放初始化重要區段物件時所配置的系統資源。 呼叫此函式之後,無法將重要區段對象用於同步處理。
當重要區段對象擁有時,唯一受影響的其他線程就是在呼叫 enterCriticalSection 中等候擁有權的線程。 未等候的線程可以自由繼續執行。
相關主題