8 操作系统第二章 进程管理 信号量 PV操作 用信号量机制实现 进程互斥、同 步、前驱关系
文章目錄
- 1 信號量機制
- 1.1 整形信號量
- 1.2 記錄形信號量
- 1.3 信號量機制小結
- 2 用信號量機制實現進程互斥、同 步、前驅關系
- 2.1 信號量機制實現進程互斥
- 2.2 信號量機制實現進程同步
- 2.3 信號量機制實現前驅關系
- 2.4 信號量機制實現進程互斥、同 步、前驅關系小結
1 信號量機制
- 用戶進程可以通過使用操作系統提供的一對原語來對信號量進行操作,從而很方便的實現了進程互斥、進程同步。
- 信號量其實就是一個變量 ,可以用一個信號量來表示系統中某種資源的數量,比如:系統中只有一臺打印機,就可以設置一個初值為1的信號量。
- 原語是一種特殊的程序段,其執行只能一氣呵成,不可被中斷。原語是由關中斷/開中斷指令實現的。
- 軟件解決方案實現臨界區的互斥主要問題是由“進入區的各種操作無法一氣呵成”,因此如果能把進入區、退出區的操作都用“原語”實現,使這些操作能“一氣呵成”就能避免問題。
一對原語:wait(S)原語和signal(S) 原語,可以把原語理解為我們自己寫的函數,函數名分別為wait和signal,括號里的信號量S其實就是函數調用時傳入的一個參數。
wait、signal原語常簡稱為P、V操作。因此常把 wait(S)、signal(S)兩個操作分別寫為P(S)、V(S)
1.1 整形信號量
用一個整數型的變量作為信號量,用來表示系統中某種資源的數量。
int S = 1; //初始化整形信號量s,表示當前系統中,某種可用資源數 wait(S){ //wait原語,相當于“進入區”while(S<=0); //若資源數不夠用,則一直循環等待S=S-1; //若資源夠用,則占用一個資源} signals(S){ //signals原語,相當于“退出區”S=S+1; //使用完資源后,在退出區釋放資源}整形信號量:
- “檢查”和“上鎖”一氣呵成, 避免了并發、異步導致的問題
- 存在的問題:不滿足“讓權等待” 原則,會發生“忙等”
1.2 記錄形信號量
整型信號量的缺陷是存在“忙等”問題,因此人們又提出了“記錄型信號量”,即用記錄型數據結構表示的信號量。
/*記錄型信號量的定義*/ typedef struct {int value; //剩余資源數struct process *L; //等待隊列 } semaphore若某個進程需要使用資源時,通過wait原語申請:
void wait( semaphore S){ //相當于申請資源S.value--;if(S.value<0){bolck(S.L) //如果剩余資源數不夠,使用block原語使進程從運行態進入阻塞態,并把掛到信號量S的等待隊列(即阻塞隊列)中} }進程使用完資源后,通過signal原語釋放:
void signal ( semaphore S ){ //相當于釋放資源s.value++;if(S.value<=0){wakeup(S.L);//釋放資源后,若還有別的進程在等待資源,則使用wakeup原語喚醒等待隊列中的一個進程,該進程從阻塞態變為就緒態} }說明:
- S.value的初值表示系統中某種資源的數目。
- 對信號量S的一次P操作意味著進程請求一個單位的該類資源,因此需要執行S.value--,表示資源數減1,當S.value<0時表示該類資源已分配完畢,因此進程應調用block原語進行自我阻塞(當前運行的進程從運行態變成阻塞態),主動放棄處理機,并插入該類資源的等待隊列S.L中。可見,該機制遵循了“讓權等待”原則, 不會出現“忙等”現象。
- 對信號量S的一次V操作意味著進程釋放一個單位的該類資源,因此需要執行S.value++,表示資源數加1, 若加1后仍是S.value<=0,表示依然有進程在等待該類資源,因此應調用wakeup原語喚醒等待隊列中的第一個進程(被喚醒進程從阻塞態變成就緒態)。
1.3 信號量機制小結
信號量的值=這種資源的剩余數量(信號量的值如果小于0,說明此時有進程在等待這種資源)
P(S)——申請一個資源S,如果資源不夠就阻塞等待
V(S)——釋放一個資源S,如果有進程在等待該資源,則喚醒一個進程
2 用信號量機制實現進程互斥、同 步、前驅關系
2.1 信號量機制實現進程互斥
思想步驟:
代碼實現:
/*記錄型信號量定義*/ typedef struct {int value; //剩余資源數struct process *L; //等待隊列 } semaphore;/*信號量機制實現互斥*/semaphore mutex=1; //初始化信號量P1(){...P(mutex); //使用臨界資源前需要加鎖臨界區代碼段...V(mutex); //使用臨界資源后需要解鎖... }P2(){...P(mutex); //使用臨界資源前需要加鎖臨界區代碼段...V(mutex); //使用臨界資源后需要解鎖... }注意問題:
2.2 信號量機制實現進程同步
進程同步:要讓各并發進程按要求有序地推進。
比如,P1、P2并發執行,由于存在異步性,因此二者交替推進的次序是不確定的。
若P2的“代碼4”要基于P1的“代碼1”和“代碼2”的運行結果才能執行,那么我們就必須保證“代碼4”一定是在“代碼2”之后才會執行。
這就是進程同步問題,讓本來異步并發的進程互相配合,有序推進。
思想步驟:
技巧口訣:前V后P
代碼實現:
以下代碼保證了P2進程中代碼4一定是在P1進程中代碼2之后執行:
注意問題:
2.3 信號量機制實現前驅關系
思想步驟:
其實每一對前驅關系都是一個進程同步問題(需要保證一前一后的操作) :
進程P1中有句代碼S1,P2中有句代碼S2,P3中有句代碼S3……P6中有句代碼S6。這些代碼要求按如下前驅圖所示的順序來執行:
前V后P V→P
2.4 信號量機制實現進程互斥、同 步、前驅關系小結
總結
以上是生活随笔為你收集整理的8 操作系统第二章 进程管理 信号量 PV操作 用信号量机制实现 进程互斥、同 步、前驱关系的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA:线程总结及多线程实现的两种方法
- 下一篇: 循环队列的介绍与实现