號誌物件
號誌物件 是同步處理物件,可維護零與指定最大值之間的計數。 每次線程完成等候號誌物件時,計數都會遞減,每次線程釋放旗號時遞增。 當計數達到零時,沒有更多線程可以成功等候信號對象狀態變成訊號。 旗號的狀態會設定為當其計數大於零時發出訊號,且當其計數為零時則為非信號。
信號對象對於控制可支援有限用戶數量的共享資源很有用。 其可作為閘道,將共用資源的線程數目限製為指定的最大數目。 例如,應用程式可能會限制它所建立的視窗數目。 它會使用最大計數等於視窗限制的號誌,在建立視窗時遞減計數,並在窗口關閉時遞增計數。 應用程式會在建立每個視窗之前,指定呼叫其中一個 等候函式的號誌物件。 當計數為零時,表示已達到視窗限制,等候函式會封鎖視窗建立程式碼的執行。
線程會使用 CreateSemaphore 或 CreateSemaphoreEx 函式來建立號誌物件。 建立線程會指定物件的初始計數和最大值。 初始計數不得小於零或大於最大值。 建立線程也可以指定信號對象的名稱。 其他進程中的線程可以藉由在呼叫 openSemaphore 函式中指定其名稱,以開啟現有旗號物件的句柄。 如需 mutex、事件、旗號和定時器物件名稱的其他資訊,請參閱 Interprocess 同步處理。
如果在號誌上等候一個以上的線程,則會選取等候的線程。 請勿假設先出先出 (FIFO) 順序。 核心模式 APC 等外部事件可以變更等候順序。
每次其中一個 等候函式 傳回,因為信號的狀態已設定為訊號,因此信號計數會減少一個。 ReleaseSemaphore 函式會以指定的數量增加號誌的計數。 計數永遠不能小於零或大於最大值。
信號的初始計數通常會設定為最大值。 然後,當取用受保護的資源時,計數會從該層級遞減。 或者,您可以在初始化應用程式時,建立具有初始計數為零的號誌,以封鎖對受保護資源的存取。 初始化之後,您可以使用 ReleaseSemaphore,將計數遞增至最大值。
擁有 Mutex 物件的線程可以重複等候相同的 Mutex 物件收到訊號,而不會封鎖其執行。 不過,重複等候相同號誌對象的線程會在每次等候作業完成時遞減旗號的計數:當計數設為零時,線程會遭到封鎖。 同樣地,只有擁有 mutex 的線程可以成功呼叫 ReleaseMutex 函式,不過任何線程都可以使用 ReleaseSemaphore 來增加號誌物件的計數。
線程可以重複指定同一個號誌物件,在呼叫任何 等候函式時重複指定相同的號誌物件,以遞減號誌的計數。 不過,使用包含相同旗號之多個句柄的陣列呼叫其中一個多重物件等候函式,不會產生多個遞減。
當您完成使用號誌物件時,請呼叫 CloseHandle 函式以關閉句柄。 當最後一個句柄關閉時,旗號對象會終結。 關閉句柄不會影響信號計數;因此,請務必先呼叫 ReleaseSemaphore,再關閉句柄或進程終止之前。 否則,暫止的等候作業將會逾時或無限期地繼續,視是否已指定逾時值而定。
相關主題