如何用結構型信號量實現互斥和同步

信號量方法的基本原則:兩個或多個進程可以用信號的方法進行協作;進程可以在任何地方停下來以等待收到特定的信號;信號的實現是用一種稱爲信號量(Semaphore)的特殊變量。

信號量S就是一個特殊變量,包含一個整數值。
在S上可以執行兩個原子操作:wait(S)用來接受信號,也稱爲P操作;signal(S)用來發送信號,也稱爲V操作。

信號量分類:計數信號量(Counting Semaphore)、二元信號量(Binary Semaphore)、結構信號量(Structure Semaphore),

結構型信號量

結構型信號量數據結構

typedef struct
{
	int value;
	struct process *L;	// L指向一個進程隊列
}

wait操作

void wait(semaphore *S)
{
	s.value--;
	if (s.value < 0)
	{
		add this process into S.L;
		block();
	}
}

signal操作

void signal(semaphore *S)
{
	s.value++;
	if (s.value <= 0)
	{
		remove a process P from S.L;
		wakeup(P);
	}
}

如何用信號量實現互斥?

用信號量實現互斥的方法:
(S.value初始值爲1)
wait(S);
臨界區
signal(S);

在這裏插入圖片描述
例如:有三個進程P、Q、R欲進入臨界區,S.value初始值爲1。P進入時,先執行wait(S),此時S.value=0,不滿足if條件,則wait結束,P進入臨界區。若此時Q想要進入臨界區,也需執行wait,此時S.value=-1,滿足<0條件,則將進程加入S,L,block阻塞進程,使其等待。同理若R想進入臨界區,則有S.value=-2,R進程也阻塞。
此時若P從臨界區出來,執行signal,此時S.value=-1,滿足if條件,從等待進程中選擇一個進入臨界區,假設按照FCFS算法,使Q進入。同理Q出臨界區後,S.value=0,R進入,R出臨界區後,S.value=1,迴歸初始值。

如何用信號量實現同步?

用信號量實現同步的方法:
S.value初始值爲0
在先執行的進程段後面加signal(S)
後執行的進程段前面加wait(S)

在這裏插入圖片描述
例子:假設有P1和P2兩個進程,要求P1進程的A段必須在P2進程的B段之前執行。
(1) 若此時P1先執行,執行完A段後,執行signal(S),此時S.value=1,不滿足signal中的if條件,不進行任何操作,結束signal。再執行P2的B段之前,執行wait(S),此時S.value=0,不滿足wait中的if條件,不進行任何操作,結束wait,執行B。
(2) 若此時P2先執行,執行B段之前先執行wait(S),此時S.value=-1,滿足wait中的if條件,B段進入S.L隊列,阻塞。執行P1中的A段,結束後執行signal(S),此時S.value=0,滿足signal中的if條件,將B移出等待隊列,喚醒B進程。

信號量取值特點
一個信號量的值可以爲負數,其絕對值表示有多少個進程等待這個信號量。
一個信號量的值可以爲正數,表示有一個或多個被積累下來的喚醒操作。

使用信號量時需要避免的錯誤
死鎖:兩個或多個進程無限地等待一個事件,而這個事件只能由這些等待進程之一來產生。
飢餓:無限期阻塞,即進程在信號內無限等待的情況。

參考文獻
北京工業大學網課《操作系統原理》金雪雲

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章