操作系統-----------進程的互斥和進程的同步超詳解!!!

一、進程的互斥:

   1.定義

        比如一臺計算機連着一臺打印機,而且現在有多個打印進程,都想要進行打印,但是打印機不可能進行多個打印進程(如果這樣做就亂套了),所以這些打印進程之間就存在着一種互斥關係,這時候 打印機可以被看成一種臨界資源,在某個時刻內只能有一個進程佔用這個臨界資源,等這個進程結束,打印機資源才被釋放,其他的進程才能使用這個臨界資源

   2.實現進程互斥的方法

        因爲打印機屬於臨界資源,所以可以用互斥信號量mutex表示,而且打印機只有一臺,所以可以令mutex=1。

/*信號量機制實現互斥*/
semaphore mutex=1//定義並初始化信號量

P1(){
	...
	P(mutex);     //使用臨界資源前需要加鎖 
	臨界代碼段..  
	V(mutex);     //使用臨界資源後需要解鎖 
	... 
}

P2(){
	...
	P(mutex);     //使用臨界資源前需要加鎖 
	臨界代碼段..  
	V(mutex);     //使用臨界資源後需要解鎖 
	... 
}

  注:P,V操作就是 wait 和 signal 操作。wait 和 signal 是一對原語,可以把原語理解成我們自己寫的函數,函數名爲 wait 

和 signal ,括號裏面的信號量其實就是函數調用時傳入的一個參數。

wait和signal函數原型:點擊這裏!!!

           這裏面有一點要注意,假設現在正在進行P1進程的P(mutex); 執行完這一行說不定就切換進程就去執行其他進程去了,原因可能是進程調度的方式不同,可能該進程的時間片用完了或者他的原因(原因有多種,這裏只是說的一種可能情況)

二、進程的同步

    1.定義

                 要讓各併發按照要求有序的推進。

P1(){               
	代碼1;
	代碼2;
	代碼3; 
} 
P2(){               
	代碼4;
	代碼5;
	代碼6; 
} 

比如上面的P1,P2進程併發執行,由於存在異步性,因此二者交替推進的次序是不確定的(可能會發生中途切換進程的情況)        

         但有時候我們會要求一定的順序,比如(c=a+b;)執行這個代碼之前要求我們首先計算出a和b的值,再去計算c的值。再比如上面的P1,P2進程,我們要求代碼4要基於代碼的程序運行,那麼我們就要保證代碼4一定實在代碼2之後纔會執行

         這就是所謂的進程同步問題,讓本來異步併發的進程互相配合,有序推進

    2.實現進程同步的方法

  用信號量實現進程同步:

1.分析爲什麼要實現”同步關係“,即必須保證”一前一後“執行的兩個操作(或兩句代碼)

2.設置同步信號量S,初始值爲0

3.在實現 ”前操作“之後執行 V(S)            ------- signal 的加操作

4.在實現 ”後操作“之前執行 P(S)            --------wait   的 減操作

還是上面的P1 P2進程,要求還是代碼4要在代碼2執行之後再執行,利用下面的方法即可實現

/*信號量機制實現同步*/
semaphore S=0;        //初始化同步信號量 

P1(){               
	代碼1;
	代碼2;
	V(S);
	代碼3; 
} 
P2(){    
	P(S);           
	代碼4;
	代碼5;
	代碼6; 
} 

分析:

情況一:若先執行到V(S) 操作,則S++後,S=1,之後執行到P(S)操作時,由於S=1,表示用可用的資源,會執行S--,

S的值變回到0,P2進程不會執行block原語,而是繼續往下執行代碼4。符合題意

情況二:若先執行到P(S)操作,由於S=0,S--後,表示此時沒有可用資源,因此P操作中會執行block原語,主動請求阻塞,之後當執行完代碼2,繼而執行V(S)操作,S++,使S變回到0,由於此時又進程在該信號量的阻塞隊列中,因此會在V操作中執行wakeup原語,喚醒P2進程,這樣P2進程就可以繼續執行代碼4了。符合題意

上面兩種情況保證了代碼4執行前代碼2肯定已經執行了

 

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