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