操作系统(经典的进程同步问提,读写者有代码演变**)

 

1.生产者消费者问题

(1)利用记录型信号量解决生产者—消费者问题

semaphore mutex=1,empty=n,full=0;
item buffer[n];   //缓冲区
int in=out=0;   //输入、输出指针
void producer()  

{    

     while(1)
    {    
         …
         生产一个产品nextp;
        …
        wait(empty);  //首先对empty--判断他是否小于0,小于0就自我阻塞
        wait(mutex);  //拿到锁,否则就自我阻塞   

        buffer[in]= nextp; //往Buffer [in]放产品
        in = (in+1) % n;
        signal(mutex);  //释放锁
        signal(full);   //对full++判断是否<=0,如果是就唤醒进程
   }
}

void consumer()  
{    
     while(1)
    {   ……
        wait(full); //首先对full--判断他是否小于0,小于0就自我阻塞
        wait(mutex); //拿到锁,否则就自我阻塞
        nextc = buffer[out]; //从Buffer [out]取产品
        out = (out +1) mod n;
        signal(mutex); //释放锁
        signal(empty); //对empty++判断是否<=0,如果是就唤醒进程
                                   消费nextc产品;
      }
}

main()
{
    cobegin{
    producer();
    consumer();
}

(2)利用AND信号量解决生产者—消费者问题

用and连接起来

semaphore mutex=1,empty=n,full=0;
item buffer[n];   //缓冲区
int in=out=0;   //输入、输出指针
void producer()  

{    

     while(1)

    {    

    …
      生产一个产品nextp;
    …
    Swait(empty, mutex);//当empty和mutex都大于0,否则自我阻塞
    buffer[in]= nextp; //往Buffer [in]放产品
    in = (in+1) mod n;
    Ssignal(mutex, full);//把锁设回来,然后full+1
     }

}

void consumer()  

{    

     while(1)

    {        

        ……

        Swait(full, mutex);当full和mutex都大于0,否则自我阻塞
        nextc = buffer[out];  //从Buffer [out]取产品
        out = (out +1) mod n;
        Ssignal(mutex, empty);把锁设回来,然后empty+1
            消费nextc产品;
         }
}

(3)利用管程解决生产者—消费者问题(待补充)

二.哲学家进餐问题

(1)利用记录型信号量解决哲学家进餐问题

Int in=0,out=0;
Item buffer[n];
Semaphore mutex=1,empty=n,full=0;//mutex为互斥变量,empty为空的缓冲区的数量,full为满的缓冲区的数量。
Void producer()
{
	Do{
		Producer an item nextp;
		……
		Wait(empty);            //生产者生产出产品减少一个空,资源
		Wait(mutex);				//防止向同一个buffer里放产品
		Buffer[in]=nextp;         //把生产出的nextp,放入buffer中,下标为in;
		In=(in+1)%n;				
		Signal(mutex);             
		Signal(full);              //增加一个慢的
	   }while(true);
}

Void customer()
{
	Do{
Wait(full);                         //注意应先执行对资源信号量的wait操作在执行对互斥信号量的wait操作,否则则可能产生进程死锁;
		Wait(mutex);
		Nextc=buffer[out];
		Out=(out+1)%n;
		Signal(mutex);
		Signal(empty);
		Consumer the item in nextc;
……
}while(true);
}

(二)利用AND信号量解决哲学家进餐问题

用Swait(empty,mutex);来代替Wait(empty),Wait(mutex);

用ssignal(mutex,full)  来代替signal(mutex),signal(full)

用ssignal(mutex,empty)来替代signal(mutex),signal(empty);

(三)利用管程解决(待补充)

三.读者—写者问题(有代码演变,很奈斯*)

(一)利用记录型信号量解决读者—写者问题

//添加代码演变过程(读者优先,即当有读者的时候写者不能操作必须排队)
1.实现读写者互斥
semaphore wmutex=1;
void reader()
{
    wait(wmutex);
    Do read operation...
    signal(wmutex);
}

void writer()
{
    wait(wmutex);
    Do write operation...
    signal(wmutex); 
}

但当一个读者将wmutex减为0时其余的无论写者还是其余的读者都不能继续操作(要求可以多个读者一起读,那就要求只允许第一个读者能操作wmutex,并且读者操作完才允许写着操作)
2.
semaphore wmutex=1;
int readcount=0;
void reader()
{
 do{
    if(readcount==0)wait(wmutex);
    readcount++;
    signal(wmutex);
    Do read operation...
    readcount--;
    if(readcount==0)signal(wmutex);
    }while(True);
}

void writer()
{  
  do{
    wait(wmutex);
    Do write operation...
    signal(wmutex); 
    }while(True);
}
//为了防止读者同时操作readcount,要对readcount进行互斥操作

3.
semaphore wmutex=1;
int readcount=0;
semaphore rmutex=1;
void reader()
{
 do{
    wait(rmutex);
    if(readcount==0)wait(wmutex);
    readcount++;
    signal(rmutex);
    signal(wmutex);
    Do read operation...
    wait(rmutex);
    readcount--;
    if(readcount==0)signal(wmutex);
    signal(rmutex);
    }while(True);
}

void writer()
{  
  do{
    wait(wmutex);
    Do write operation...
    signal(wmutex); 
    }while(True);
}

食用须知:第三个复杂有过程演变,待补充用管程实现

猜你喜欢

转载自blog.csdn.net/mnhdxhcky/article/details/82935369