经典进程同步问题——读者写者

读者-写者问题

问题描述:有读者和写者两组并发进程,共享一个文件,当两个或以上的读进程同时访问共享数据时不会产生副作用,但是如果某个写进程和其他进程(读进程或写进程)同时访问共享数据时则可能导致数据不一致的错误。简单来说,你可以一个文档打开好多,但是你不能边读边写。从上述来看,得满足以下几个要求。

①允许多个读者可以同时对文件执行读操作;

②只允许一个写着往文件中写信息。

③任一写着再完成写操作前不允许或其他读者或写者工作;

④写者执行写操作前,应让已有的读者和写着全部退出。

问题分析

  1. 关系分析。可以看出读者和写者是互斥,写者和写者也是互斥,读者和读者不存在互斥。
  2. 整理思路。两个进程,读者和写着。写者比较容易实现,它和任何进程互斥,用互斥信号量P和V可以解决。读者比较复杂,它必须在实现与写者互斥的同时,实现与其他读者同步,因此一对P和V是无法解决问题的。这里用到了一个计数器count,用它来判断是否由读者读文件。当有读者时,写者无法写文件,当没有读者时,写者才可以写文件。同时,这里不会读者对计数器的访问也应该是互斥的。
  3. 信号量设置。count计数器,用于记录当前读者的数量,初始值为0;设置mutex为互斥信号量,用于保护更新count变量时的互斥;设置互斥信号量rw,用于保证读者和写者的互斥访问。

代码描述如下:

  1. int count=0;//用于记录当前的读者数量  
  2. semaphore mutex=1;//用于保护更新count变量时的互斥  
  3. semaphore rw=1;//用于保证 读者和写者互斥地访问文件  
  4. writer(){ //写者进程  
  5.   while(1){  
  6.     P(rw); //互斥访问共享文件  
  7.     writing;//写入  
  8.     V(rw);//释放共享文件  
  9.   }  
  10. }  
  11. reader(){//读者进程  
  12.   while(1){  
  13.    P(mutex);//互斥访问count变量  
  14.    if(count==0) //当第一个读进程读共享文件时  
  15.       P(rw);    //阻止写进程  
  16.    count++;     //读者+1  
  17.    V(mutex);    //释放互斥变量count  
  18.    reading;     //读取  
  19.    P(mutex);    //互斥访问count变量  
  20.    count--;     //读者减1  
  21.    if(count==0) //没有读者了  
  22.       V(rw);    //允许写进程写  
  23.    V(mutex);    释放互斥变量count  
  24.   }  
  25. }  

从上述可以看出,读进程是优先的,只有出现了读进程,那么写操作就会被延迟,且只要有一个读进程活跃,那么它后面的都允许访问文件。这样会让写进程一直等待,会出现饿死的情况。如果要写进程优先的话,只要在读写进程上增加一对PV操作即可,代码描述如下,黑色加粗为增加的地方。

  1. int count=0;//用于记录当前的读者数量  
  2. semaphore mutex=1;//用于保护更新count变量时的互斥  
  3. semaphore rw=1;//用于保证 读者和写者互斥地访问文件  
  4. semaphore w=1;//用于实现“写优先”  
  5. writer(){ //写者进程  
  6.   while(1){  
  7.     P(w);//在无写进程请求时进入  
  8.     P(rw); //互斥访问共享文件  
  9.     writing;//写入  
  10.     V(rw);//释放共享文件  
  11.     V(w);//恢复对共享文件的访问  
  12.   }  
  13. }  
  14. reader(){//读者进程  
  15.   while(1){  
  16.    P(w);//在无写进程请求时进入  
  17.    P(mutex);//互斥访问count变量  
  18.    if(count==0) //当第一个读进程读共享文件时  
  19.       P(rw);    //阻止写进程  
  20.    count++;     //读者+1  
  21.    V(mutex);    //释放互斥变量count  
  22.    V(w);//恢复对共享文件的访问  
  23.    reading;     //读取  
  24.    P(mutex);    //互斥访问count变量  
  25.    count--;     //读者减1  
  26.    if(count==0) //没有读者了  
  27.       V(rw);    //允许写进程写  
  28.    V(mutex);    释放互斥变量count  
  29.   }  
  30. }  

其实这里的写优先是相对的,并不是真正的写进程优先,有些书上,也把这个算法成为读写公平法,它只是不会让写进程“饿死”。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值