並發問題-互斥(Dekker算法和Peterson算法)


P1,P2,...,Pn互斥: 軟件方法

      軟件方法能夠實現並發過程在一個或多個共享主存的處理器上執行。這些方法通常基於在訪問內存是基本互斥條件的假設,也就是說,盡管允許訪問的順序事先沒有安排,但同時訪問主存中的同一地址的操作(讀或寫)被內存仲裁器串行化了。此外,也沒有考慮硬件、操作系統或是編程語言的支持。

 全局變量

enmu blooean(false=0;true=1);

boolean flag[2]={0,0};

 

Dekker算法如下: 

當P0要進入它的臨界區時,它設置它的flag為true,然后檢查P1的flag,如果為false,則P0可以立即進入它的臨界區,否則,P0咨詢true,如果發現turn=0,那么它知道要持續並周期性地檢查P1的flag。P1知道需要它延期執行並設置flag為false,以讓P0執行。P0用完臨界區之后設置它的flag為false以釋放臨界區,設置turn為1,把權力轉交給P1。

構造parbegin(P1,P2,...,Pn)的意思是,擱置主程序的執行,初始化並發執行程序P1,P2,...,Pn,當所有的程序P1,P2,...,Pn都結束后,重新開始主程序。

 

boolean flag[2];
int turn;
void P0()
{
while(true)
{
flag[0]=true;
while(flag[1])
if(turn==1)
{
flag[0]=false;
while(turn==1)
/* do nothing */;
flag[0]=true;
}
/* critical section */;
turn=1;
flag[0]=false;
/* remainder */
}
}
void P1()
{
while(true)
{
flag[1]=true;
while(flag[0])
if(turn==0)
{
flag[1]=flase;
while(turn==0)
/* do nothing */;
flag[1]=true;
}
/* critical section */;
turn=0;
flag[1]=false;
/* remainder */;
}
}
void main()
{
flag[0]=false;
flag[1]=false;
turn=1;
parbegin(P0,P1);
}

 

Peterson算法如下:

Peterson提出了簡單且一流的方法。 和以前一樣,全局數組變量flag表明每個互斥進程的位置,全局變量turn解決同時發生的沖突。

boolean flag[2];
int turn;
void P0()
{
while(true)
{
flag[0]=true;
turn=1;
while(flag[1]&&turn==1)
/* do nothing */
/* critical section */
flag[0]=false;
/* reminder */
}
}
void P1()
{
while(true)
{
flag[1]=true;
turn=0;
while(flag[0]&&turn==0)
/* do nothing */
/* critical section */
flag[1]=false;
/* reminder */
}
}
void main()
{
flag[0]=false;
flag[1]=false;
parbegin(P0,P1);
}

 

 考慮進程P0,一旦它設置flag[0]為true,則P1不能進入臨界區。如果P1已經進入臨界區,那么flag[1]=true,P0被阻塞不能進入臨界區。

 這樣就有了一種簡單的方法解決兩個進程的互斥問題。此外Peterson算法可以很容易地推廣到n個進程的情況。另一方面,互相阻塞也避免了。假如P0在while循環里被阻塞了,這表示flag[1]為true,當flag[1]變為false或true變為0時,P0都可以進入臨界區。

 



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM