1.進程同步的概念
在多道程序程序環境下,進程併發執行時,不同進程之間存在不同相互制約的關係;
引入進程同步,協調了進程之間的相互制約關係;
1)臨界資源
一次只允許一個進程使用的資源,即臨界資源,例:共享變量、共享數據結構、打印設備等;
臨界區訪問的四個部分:1)進入區;2)臨界區;3)推出區;3)剩餘區;
2)同步
同步亦是直接制約關係,源於進程之間的相互協作進程之間在某種任務中,協調工作次序並等待、傳遞信息的制約關係;
注:同步與異步,同步即在一條路上大家先後走,異步即大家各自走不一樣的路兩路不影響;
3)互斥
互斥是相對於臨界資源的進程排斥關係,一個進程在使用臨界資源時,另一進程需等待,當前佔用臨界資源進程退出使用後,才能訪問使用臨界資源;
互斥原則:
1)空閒讓進,臨界區空間,允許一個進程進入;
2)忙則等待,以有進程在臨界區,其他進程等待;
3)有限等待,等待進程等待時間有限;
4)讓權等待,進程不進入臨界區,釋放處理去,防止“忙等”進程;針對while循環等待;
2.臨界區的互斥方法
1)軟件實現
1)單標誌法,
算法思想:進程與進程之前傳遞讓步標誌訪問臨界資源;
缺點,違反空閒讓進原則
2)雙標誌法先檢測 和 雙標誌法後檢測
雙標誌先檢測,先檢查,再上鎖,檢查,鎖爲兩個標誌
雙標誌先檢測法違反忙則等待原則
雙標誌後檢測法,先上鎖,再檢查;
雙標誌後檢測法違反空閒讓進、有限等待原則,會導致“飢餓”現象;
3)The algorithm of Peterson,皮特森算法
算法思想:結合單標誌法和雙標誌法,有爭取、有讓步;
解決了兩進程互斥防衛臨界區,遵循了空閒進入、忙則等待、有限等待;
但爲遵循讓權等待,當進程長時間堵在while循環不釋放處理器;
2)硬件實現
1)中斷屏蔽法;2)硬件指令法(Test-and-Set指令或Swap指令)
軟件實現互斥總結圖:
硬件實現互斥總結圖:
3.信號量機制
前面的算法都不能實現讓權等待原則
使用PV操作原句對臨界資源的同步、互斥訪問;wait(S)、signal(S);
1.整型信號量
wait(S){ while(S<=0);//資源不夠等待; S--;//佔用一個資源,信號量減1 } signal(S){ S++;//資源釋放,信號量+1; }
2.記錄型信號量
typedef struct{ int value;//信號量值,資源個數 struct process *L;//等待進程隊列,可順序可鏈式 }semaphore; void wait(semaphore S){ S.value--;//先佔用一個資源,只有最後一個資源時,--後value=0; if(S.value<0){//資源消耗完;--後value=-1; add current_process to S.L; block(S,L);//阻塞 } } void wait(semaphore S){ S,value++; if(S.value<=0){//value=0時資源還有1個; remove a process P from S.L;//取出一個等待進程; wakeup(P);//喚醒該進程; } } //block()、wakeup()實現對進程的讓權等待原則
3.進程的互斥
semaphore mutex=1;//互斥型號量設置爲1,默認信號量爲記錄型信號量 P1(){ ....; P(mutex);//matux--;佔用唯一資源 臨界區; V(mutex);//釋放資源,並喚醒等待進程; ....; } P2(){ ....; P(mutex);//matux--;佔用唯一資源 臨界區; V(mutex);//釋放資源,並喚醒等待進程; ....; }
4.進程的同步
//確定x操作一定再y操作之前,既滿足同步; semaphore S=0;//設置同步信號量爲0; P1(){ ....; x;//x操作 V(S);//S++,信號量不爲0,P(V)不用等待; ....; } P2(){ ....; P(S);//若信號量>0,不要等待即x操作已執行完;若信號量爲0則x未操作完,進程阻塞,等待被喚醒; y;//y操作 ....; }
進程的同步、互斥
4.管程
對進程同步互斥的操作進行封裝的產物;
5.經典同步問題
1)生產者消費者問題(同步、互斥)
問題描述:多個相同生產者和多個相同消費者共享一個大小爲n的緩衝區,緩衝區有空時,生產者才能生產,緩衝區有產品時,消費者才能消費,否則等待;緩衝區爲臨界資源,只允許一個生產者或消費者對其生產或消費;
同步問題:1)緩衝區有空時,生產者才能生產 ;2)緩衝區有產品時,消費者才能消費
互斥問題:緩衝區爲臨界資源,只允許一個生產者或消費者對其生產或消費;
semaphore empty=n;//緩衝區剩餘數量,初始爲緩衝區大小 semaphore full=0;//緩衝區生產的產品個數,即佔用的個數,初始爲0,空閒,未有產品; semaphore mutex=1;//互斥信號量 producer(){ while(1){ 生產一個產品; P(empty);//佔用一個 P(mutex);//佔用互斥信號量,其他所有P(mutex)等待; 放入產品;//對臨界區的操作,用PV操作互斥包裹,只有一個進程對它操作; V(mutex);//釋放信號量,喚醒一個P(mutex)等待進程 V(full);//告訴生產者,已生產一個產品,有等待消費進程則喚醒,消費者進程爲就緒態; } } consumer(){ while(1){ P(full);//緩衝區中產品-1,申請消費 P(mutex); 取出產品;//對臨界區的操作,用PV操作互斥包裹 V(mutex); V(empty);//告訴消費者,已消費一個產品,empty空閒空間+1,有等待生產進程則喚醒; 消費一個產品; } }
注:
實現互斥與同步之間的兩個P操作的先後順序會造成死鎖現象,兩個進程都在等待對方釋放互斥信號量;
但V操作的前後順序沒有嚴重影響;
複雜的生產者消費者問題(同步、可不需互斥)
不同生產者和不同消費者問題:
一個盤子,只允許放一個水果;父親只能放蘋果,媽媽只能放橘子,女兒只等喫蘋果,兒子只等喫橘子;爸爸或媽媽只能在牌子空時才能放,兒子女兒盤子有自己想要的水果才能取走;
一個互斥問題:
對盤子的放入水果和取走水果;//臨界區的大小爲1;
三個同步問題:
父親放入蘋果事件和女兒取走蘋果事件的先後順序;
母親放入橘子事件和兒子取走橘子事件的先後順序;
女兒取走蘋果事件觸發盤子爲空,則需要父親或母親放入;
兒子取走橘子事件觸發盤子爲空,需要父親或母親放入;
將問題事件的先後順序描述爲前驅圖(前V後P);
[外鏈圖片轉存失敗(img-Vgeb5ytL-1569478183236)(C:\Users\lin\AppData\Roaming\Typora\typora-user-images\1569304505753.png)]
semphore plate=1,//共享區域大小 apple=0, orange=0, //mutex=1;//共享區域大小爲1則當前只有一個進程佔用,若邏輯符合則不需要互斥遍歷;這裏可以不需要,即用PV操作包裹放入盤子,盤中取走; father(){ while(1){ 弄一個蘋果; P(plate); //P(mutex);//之後進程省略 放入盤子 //V(mutex); V(apple); } } mather(){ while(1){ 弄一個橘子; P(plate) 放入盤子; V(orange); } } daughter(){ while(1){ P(apple);//等待蘋果 盤中取走蘋果; V(plate);//喚醒等待盤子的爸爸或媽媽 eat...; } } son(){ while(1){ P(orange);//等待橘子 盤中取走橘子; V(plate);//喚醒等待盤子的爸爸或媽媽; eat...; } }
2)讀寫者問題(互斥)
經典複雜互斥問題;
問題描述:多讀寫者進程併發執行(寫,是往文件里加,讀,只是讀不改變文件大小,不是消費),共享一個文件,當兩個或以上的讀進程同時讀不會產生副作用,但若某個寫進程和其他寫進程同時訪問共享數據時可導致數據的不一致;故應滿足如下要求:
1)允許多個讀者同時讀;2)只允許一個寫者寫;3)寫時不允許讀;4)讀時允許寫;
分析:
互斥關係
1)寫者與寫者互斥;2)讀者與寫者互斥;3)讀者和讀者不存在互斥關係;
隱含讀寫之間的優先或公平問題
讀者優先,寫者可能長期處於飢餓狀態;
寫進程優先,即讓當前讀者不再增加,等待原讀進程讀完,執行寫進程;這樣的寫進程優先是相對而言的,也稱讀寫公平法;
3)哲學家進餐問題
哲學家進餐的問題關鍵在於解決進程死鎖;
這些進程只存在互斥關係,但與之前其他問題的互斥關係不同的是,哲學家問題進程需要同時持有兩個臨界資源,才能執行想要執行的操作,因此就會存在“死鎖”的問題;
注:死鎖,進程需要兩個或以上的資源時可能會產生都有部分資源但都需等待對方釋放資源,造成都等待的死鎖現象;
參考哲學家進餐問題可以解決死鎖的三種思路;
總結:
1)爲什麼要引入進程同步的概念?
在多道程序程序環境下,進程併發執行時,不同進程之間存在不同相互制約的關係;
引入進程同步,協調了進程之間的相互制約關係;
2)同步、互斥是什麼?
同步時是進程之間在某種任務中,協調工作次序並等待、傳遞信息的制約關係;
互斥是相對於臨界資源的進程排斥關係,一個進程在使用臨界資源時,另一進程需等待,當前佔用臨界資源進程退出使用後,才能訪問使用臨界資源;
3)怎麼產生死鎖現象呢?
進程在執行過程中佔有一些資源,且都需要等待對方釋放資源的執行,產生一直互相等待的現象,即死鎖;