并发问题-互斥(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都可以进入临界区。

 



 

posted @ 2012-01-11 15:05  在云中漫步  阅读(5308)  评论(3编辑  收藏  举报