進程同步與信號量、信號量臨界區保護、信號量代碼實現

生產者-消費者實例

在這裏插入圖片描述
生產者發現 counter == BUFFER_SIZE 生產者等待(阻塞)
消費者發現 counter == 0 消費者等待(阻塞)

存在問題:

在這裏插入圖片描述
只用counter做判斷,在圖中情況下會導致P2不會被喚醒。
應該需要另一量(信號量)考慮記錄有多少進程阻塞等信息,並進行判斷。

信號量

在這裏插入圖片描述
在這裏插入圖片描述
sem < 0表示 sem 有多個進程在等待
sem > 0 表示有空閒
在這裏插入圖片描述
B,有2個資源可以使用

信號量的定義

在這裏插入圖片描述
queue代表阻塞隊列

V()的模型:

V(semaphore s)
{
	s.value++;
	if(s.value <= 0)
	{
		wakeup(s.queue);
	}
}

用信號量解決生產者-消費者問題

在這裏插入圖片描述
empty 表示空閒緩衝區,當緩衝區空時,生產者等待。full 表示緩衝區使用的數量,與empty相反。
Producer()中,作爲生產者,P(empty)V(full),test 有沒有空閒緩衝區。
Consumer()中,作爲消費者,P(full),V(empty),test 緩衝區是否爲空
生產者什麼時候會停?
當緩衝區爲滿時,空閒緩衝區爲空時。
消費者什麼時候會停?
當緩衝區爲空時,緩衝區全部空閒時。

mutex 互斥信號量,初值爲1

....
P(mutex) //申請鎖 mutex --
{
	......
}
V(mutex)//釋放鎖 mutex ++;
....

由於mutex初值爲1,當進程A申請鎖時(P(mutex)),mutex --,此時爲0
若此時進程B也申請鎖,由於此時進程A已上鎖,P(mutex)將會使mutex0改爲 -1,此時進程將被sleep()
進程A執行完畢,釋放鎖(V(mutex)),會使mutex-1改爲0,將喚醒進程B,進程B取得鎖。
進程B執行完畢,釋放鎖(V(mutex)),將會使mutex恢復至1.

信號量臨界區保護

**什麼是信號量?**通過對這個量的訪問和修改,讓大家有序推進。
爲什麼要保護信號量?
既然要對這個量訪問和修改,那麼一定會出現 競爭條件
在這裏插入圖片描述
競爭條件:和調度有關的共享數據語義錯誤。
在這裏插入圖片描述
在這裏插入圖片描述
臨界區:
在這裏插入圖片描述
讀寫信號量的代碼一定是臨界區,加以保護。

保護原則:
在這裏插入圖片描述

臨界區保護的方法

輪換法:

在這裏插入圖片描述

標記法:

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
非對稱標記:
在這裏插入圖片描述

標記與輪換的綜合:Peterson算法

在這裏插入圖片描述
flag[i] 可以理解爲:當前要執行i進程
turn = j 可以理解爲: 接下來執行j進程

在這裏插入圖片描述

多個進程:麪包店算法

在這裏插入圖片描述
在這裏插入圖片描述

硬件法:關中斷

在這裏插入圖片描述
調度由中斷產生,控制中斷可以組織調度,cli()關中斷,sli()開中斷
多CPU(多核)無效的原因cli()sli() 會使當前CPU忽略INTR寄存器上的中斷標記,但無法控制其他CPU。

硬件法:原子指令法

在這裏插入圖片描述

信號量代碼實現

在這裏插入圖片描述
(1)信號量數據結構以及應該在內核態,用戶態應定義系統調用:sem_open(),調用sem_open()進入內核態調用sys_sem_open()sys_sem_open()中創建信號量。
(2)此生產者要在文件中寫入5個數:寫之前判斷是否有空閒緩衝區:sem_wait()sys_sem_wait中實現P(empty)的功能:

....
cli();//保護信號量
if(semtable[sd].value -- < 0)
	sleep_on(current);
	(semtable[sd].queue).push(current); //加入隊列,具體實現略
	schedule();
sti();
....

Linux 0.11 中:
在這裏插入圖片描述

  1. 獲取空閒緩存
  2. 啓動讀入(上鎖)
    在這裏插入圖片描述
    sleep_on 的實現:
    在這裏插入圖片描述
    四:進程運行軌跡的跟蹤與統計中提到了sleep_on的實現,這個隊列的實現及其巧妙。
    在這裏插入圖片描述
    在這裏插入圖片描述
    wake_up會將等待隊列全部喚醒,然後根據優先級獲取資源。
    再回頭看lock_buffer():因爲全部喚醒,優先級最高的會上鎖,其他的再次睡眠。
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章