複製鏈接
請複製以下鏈接發送給好友

信號標

鎖定
信號標(Semaphore),有時被稱為信號燈,是在多線程環境下使用的一種設施, 它負責協調各個線程, 以保證它們能夠正確、合理的使用公共資源。
中文名
信號標
外文名
signal beacon

信號標概念

Semaphore分為單值和多值兩種,前者只能被一個線程獲得,後者可以被若干個線程獲得。
以一個停車場是運作為例。為了簡單起見,假設停車場只有三個車位,一開始三個車位都是空的。這時如果同時來了五輛車,看門人允許其中三輛不受阻礙的進入,然後放下車攔,剩下的車則必須在入口等待,此後來的車也都不得不在入口處等待。這時,有一輛車離開停車場,看門人得知後,打開車攔,放入一輛,如果又離開兩輛,則又可以放入兩輛,如此往復。
在這個停車場系統中,車位是公共資源,每輛車好比一個線程,看門人起的就是信號量的作用。
更進一步,信號量的特性如下:信號量是一個非負整數(車位數),所有通過它的線程(車輛)都會將該整數減一(通過它當然是為了使用資源),當該整數值為零時,所有試圖通過它的線程都將處於等待狀態。在信號量上我們定義兩種操作: Wait(等待) 和 Release(釋放)。 當一個線程調用Wait(等待)操作時,它要麼通過然後將信號量減一,要麼一直等下去,直到信號量大於一或超時。Release(釋放)實際上是在信號量上執行加操作,對應於車輛離開停車場,該操作之所以叫做“釋放”是因為加操作實際上是釋放了由信號量守護的資源。
在java中,還可以設置該信號量是否採用公平模式,如果以公平方式執行,則線程將會按到達的順序(FIFO)執行,如果是非公平,則可以後請求的有可能排在隊列的頭部。
JDK中定義如下:
Semaphore(int permits, boolean fair) 創建具有給定的許可數和給定的公平設置的Semaphore。

信號標信號標

信號量(英語:Semaphore)又稱為信號量旗語,是一個同步對象,用於保持在0至指定最大值之間的一個計數值。當線程完成一次對該semaphore對象的等待(wait)時,該計數值減一;當線程完成一次對semaphore對象的釋放(release)時,計數值加一。當計數值為0,則線程等待該semaphore對象不再能成功直至該semaphore對象變成signaled狀態。semaphore對象的計數值大於0,為signaled狀態;計數值等於0,為nonsignaled狀態.
semaphore對象適用於控制一個僅支持有限個用户的共享資源,是一種不需要使用忙碌等待(busy waiting)的方法。
信號量的概念是由荷蘭計算機科學家艾茲赫爾·戴克斯特拉(Edsger W. Dijkstra)發明的,廣泛的應用於不同的操作系統中。在系統中,給予每一個進程一個信號量,代表每個進程目前的狀態,未得到控制權的進程會在特定地方被強迫停下來,等待可以繼續進行的信號到來。如果信號量是一個任意的整數,通常被稱為計數信號量(Counting semaphore),或一般信號量(general semaphore);如果信號量只有二進制的0或1,稱為二進制信號量(binary semaphore)。在linux系統中,二進制信號量(binary semaphore)又稱互斥鎖(Mutex)。

信號標語法

計數信號量具備兩種操作動作,之前稱為 V(又稱signal())與 P(wait())。 V操作會增加信號量 S的數值,P操作會減少它。
運作方式:
  1. 初始化,給與它一個非負數的整數值。
  2. 運行 P(wait()),信號量S的值將被減少。企圖進入臨界區塊的進程,需要先運行 P(wait())。當信號量S減為負值時,進程會被擋住,不能繼續;當信號量S不為負值時,進程可以獲准進入臨界區塊。
  3. 運行 V(又稱signal()),信號量S的值會被增加。結束離開臨界區塊的進程,將會運行 V(又稱signal())。當信號量S不為負值時,先前被擋住的其他進程,將可獲准進入臨界區塊。

信號標WindowsAPI提供的semap

線程使用CreateSemaphore或CreateSemaphoreEx函數創建一個semaphore對象。此時可以指定semaphore的當前計數值與計數值上限;也可指定semaphore對象的名字。其他進程中的線程可以指出已存在的semaphore對象的名字通過調用OpenSemaphore函數打開它。
如果多個線程在等待一個semaphore對象,不保證按照先進先出(FIFO)順序調度這些等待線程。外部事件,如內核模式的異步過程調用可改變等待順序。
在semaphore對象為signaled狀態時,等待函數返回會把該semaphore對象計數值減1。函數ReleaseSemaphore把semaphore對象的計數值增加指定的值。任何線程,哪怕它沒有等待完成過該semaphore對象,也可以使用ReleaseSemaphore來增加semaphore對象的計數。如果ReleaseSemaphore導致對象計數值超過上限,則該函數調用失敗,返回298號錯誤:“Too many posts were made to a semaphore”。
一個線程多次等待同一個semaphore對象,每次等待操作完成都會降低semaphore對象計數值(直至計數值為0時該線程阻塞)。然而,通過multiple-object等待函數使用一個數組包含着同一個semaphore對象的多個句柄,不能實現對這個semaphore對象計數值的多次下降。
用完semaphore對象後,調用CloseHandle函數關閉它。semaphore對象的最後一個句柄被關閉後,操作系統會摧毀它。關閉semaphore並不影響它的計數值。因此,關閉semaphore前或者進程終止前,要確保已經正確調用過ReleaseSemaphore。否則,掛起等待該semaphore對象的線程會永久阻塞或超時返回 [1] 
參考資料
  • 1.    王飛, 龍騰. 一種新的步進頻率雷達信號目標抽取算法[J]. 彈箭與制導學報, 2006, 26(2):135-137.