在鎖變數機制中,有時Process讀取鎖變數的舊值並進入臨界區。由於這個原因,多個流程可能會進入臨界區。但是,下面第一部分中顯示的程式碼可以用第二部分中顯示的程式碼替換。這不會影響演算法,但通過這樣做,我們可以設法在一定程度上提供互斥,但不能完全實現。
在更新版本的程式碼中,Lock的值被載入到本地暫存器R0中,然後鎖的值被設定為1
。
但是,在步驟3中,先前的鎖定值(現在儲存到R0中)與0進行比較,如果該值為0
,則該過程將簡單地進入臨界區域,否則將通過迴圈連續執行來等待。
將進程本身立即設定為1的好處是,現在進入臨界區的進程攜帶的鎖變數的更新值為1
。
在它被搶占並重新計劃的情況下,它也不會進入臨界區,而不管當前鎖定變數的值如何,因為它已經知道鎖定變數的更新值是什麼。
第一部分
1. Load Lock, R0
2. CMP R0, #0
3. JNZ step1
4. store #1, Lock
第二部分
1. Load Lock, R0
2. Store #1, Lock
3. CMP R0, #0
4. JNZ step 1
但是,上述部分提供的解決方案在一定程度上提供了相互排斥,但不能確保互斥將始終存在。臨界區可能有多個流程。
在執行第2節中編寫的組合程式碼的第一條指令之後,如果進程被搶先,該怎麼辦?在這種情況下,它將攜帶舊的鎖定變數值,並且無論知道鎖定變數的當前值,它都將進入臨界區域。這可能會使兩個進程同時出現在臨界區。
要擺脫這個問題,必須確保在載入先前的鎖定變數值之前並且在將其設定為1
之前不應該發生搶占。如果能夠合併前兩個說明。
為了解決這個問題,作業系統提供了一個稱為測試集鎖定(TSL)指令的特殊指令,該指令簡單地將鎖定變數的值載入到本地暫存器R0
中,並將其同時設定為1
。
首先執行TSL的過程將進入臨界區,之後不會進入其他進程,直到第一個進程出來。即使在搶先執行第一個過程的情況下,任何進程都不能執行臨界區。
解決方案的組合程式碼如下所示。
以四個條件為基礎來考察TSL。
相互排斥
在TSL機制中保證相互排斥,因為在設定鎖變數之前,進程永遠不會被搶占。 只有一個進程可以在特定時間將鎖變數看作0,這就是為什麼互斥可以保證執行。
進程
根據進程的定義,不想進入臨界區的進程不應該阻止其他進程進入進程。 在TSL機制中,進程只有在想要進入臨界區時才會執行TSL指令。 如果沒有進程不想進入臨界區,鎖的值將始終為0,因此在TSL中始終保證進程。
有界等待
TSL不保證有限等待。 有些過程可能沒有這麼長時間。 我們無法預測一個進程,在一段時間之後,它肯定會有機會進入臨界區。
架構中立
TSL不提供架構中立。 這取決於硬體平台。 TSL指令由作業系統提供。 有些平台可能不會提供。 因此它不是架構中立的。