读者写者问题

#问题描述


  • 读者写者两组并发进程,共享文件,当两个或两个以上的读进程同时访问共享数据时不会产生副作用,但某个写进程和其他进程同事访问共享数据时则可能导致数据不一致的错误。
  • 故要求
  • 1.允许多个读进程可以同时对文件进行读操作
  • 2.只允许一个写进程向文件中写入信息
  • 3.任意写进程在写操作完成之前不允许其他读或写进程工作
  • 4.写进程执行写操作之前应该让已有的读进程和写进程全部退出
  • 说白了,读操作可以同时读,写操作只能单独写
  • 至于你问要是读写串操作,啧啧,你学过的数据结构告诉你,这叫牛头不对马嘴
  • *核心思想*
  • 设置一个计数器count来记录正在访问共享文件的进程数,可以用count的值来判断当前进入的进程是否是第一个/最后一个读进程,从而做出不同的处理
  • *为了实现代码的“一气呵成”自然要想到互斥信号量*
  • #详细说道


  • 不保证写优先
  • 设置信号量,rw=1,目的保证写进程与写进程互斥,写进程与读进程互斥访问
  • 设置计数器count,count=0,目的保证读进程知道“第一个进门开门,最后一个出门关门”原理
  • 设置互斥信号量,mutex,mutex=1,目的保证读进程间互斥访问count,防止因为并发中断操作
  • writer进程
  • P(rw)
  • 写文件
  • V(rw)
  • reader进程
  • P(mutex)//访问count,需要互斥访问
  • if(count\==0)//如果是ture则是第一个访问,需要上锁
  • P(rw)
  • count++//计数器加一
  • V(mutex)//释放mutex,让其他读进程进入
  • 读文件
  • P(mutex)//访问count,互斥
  • - count--//计数器减一
  • if(count\==0)//如果是最后一个退出,需要解锁
  • V(rw)
  • V(mutex)//释放mutex
  • 这里就体现了*核心思想*,关于互斥一气呵成妙用,关于计数器多个进程同时访问
  • 但是呢,这样设置不保证写优先,保证了读优先,嗯,这可能会导致写进程*饿死
  • 公平读写
  • 在上述的信号量设置上,再添一个w=1
  • w的目的就是保证读写进程能够一起排队等资源
  • write进程
  • P(w)//此处上锁是有大用的,在读进程里体现
  • P(rw)
  • 写文件
  • V(rw)
  • V(w)
  • reader进程
  • P(w)//让读进程和写进程联系起来一起排队
  • P(mutex)//访问count,需要互斥访问
  • if(count\==0)//如果是ture则是第一个访问,需要上锁
  • P(rw)
  • count++//计数器加一
  • V(mutex)//释放mutex,让其他读进程进入
  • V(w)//释放w,唤醒其他阻塞进程
  • 读文件
  • P(mutex)//访问count,互斥
  • - count--//计数器减一
  • if(count\==0)//如果是最后一个退出,需要解锁
  • V(rw)
  • V(mutex)//释放mutex
  • 在reader进程里,用一对PV操作把读文件前的程序圈起来
  • 如果多个读写进程并发运行,必然有一个进程运行,其他进程均在w信号量下排队等候
  • 直到该进程释放w
  • 你可以自己分析下,很有趣的思路,这就保证了读写进程公平访问文件了