2017-04-12 71 views
0

剛剛觀看了一個關於信號量的視頻,並試圖挖掘更多信息。不太清楚信號燈如何在組件級別上工作。不理解信號量低層

P(s): 
    s = s - 1 
    if (s < 0) {wait on s} 

CRITICAL SECTION 

V(s): 
    s = s + 1 
    if(threads are waiting on s) {wake one} 

我明白這些功能背後的概念是什麼,但是我無法繞開這個念頭。

說S = 1 ,你有2個線程:線程1和線程2

Thread One          Thread Two 
load s           load s 
subtract s,1         subtract s,1      
save s           save s 

然後是在減法之間的上下文切換和保存兩個設定s至0兩者。不會兩個線程都將s看作0進入關鍵部分。我不確定如果一個線程可以在彙編級別上下文切換以使兩個線程都可以看到s = 0,那麼這個線程是如何獨佔的。

+0

您忘記了故障中的「等待」部分。 –

+0

不確定你的意思? S上有一個互斥量嗎? – train55255

+0

不,不是互斥體,而是信號量。它是一種不同的同步機制,但就像互斥體一樣,它通常提供高效*阻塞*,即它與OS調度程序交互。 –

回答

2

關鍵是增量和減量使用原子指令。在x86中,有一種添加指令的形式,它與鎖前綴結合使用,可以以原子方式執行對內存位置的添加。由於它是單個指令,因此在執行過程中不會發生上下文切換,並且鎖定前綴意味着CPU確保在增量過程中不會出現其他任何訪問。

如果原子添加不可用,那麼還有其他選項。一個常見的是原子比較和交換指令。在大多數支持並行或併發代碼的系統上發現,它是一個指令,它帶有兩個值,一個是舊的,一個是新的,如果內存位置等於舊的,則將其設置爲新值。這可以在循環中用於實現原子添加:

l: 
load r0 s 
mov r1 r0 
add r0 -1 
cas s r1 r0 
jmpf l 

這會加載一個值,然後從該值的副本中減去1。然後我們嘗試存儲較低的值,但如果它發生了變化,我們將失敗並重新開始。

+0

非常感謝你,我隱約記得我的教授說,在講座中,這些指示是原子性的,但是你只是清除了所有這些,並把它打在頭上。非常感謝! – train55255

+0

希望我的教授能多走一步,再深入一點,再次感謝你。但是,這不會變得低效。說一下,如果有很多上下文切換,你是否會遇到試圖添加或減少的四條指令? – train55255