进程同步中的读者写者问题(写者优先)

写者优先问题

  • 由于读-写、写-写互斥,使用信号量file控制临界区访问

    • 一群读者在读取时若有写者进来,会在队列占有quemutex,等待最后一个正在读的人离开释放file,然后立刻开始写
  • 使用一个readcount整型变量计数器,记录读者数量,用信号量rdcntmutex控制该变量的访问;writecount记录写者数量,需要信号量wrtcntmutex控制该变量访问

  • 为了实现写者优先,那么不能按照读者写者来的先后顺序排队,故设置两个队列,优先队列quemutex和读者等待队列readEntry

    • 当一个写者来时占用优先队列quemutex,一直占有到最后一个写者离开才能释放
    • 当一个读者来时放到readEntry排队,若此时前面没有其他读者,也没有写者,它才可以进到quemutex"就绪区",quemutex仅允许一个读者存在
    • 后续所有的读进程要统一放到readEntry等待。
    • 直到所有的写进程都写完了,才会唤醒quemutex中的唯一读者,该读者完成任务后,才会唤醒readEntry的第一个读者进入quemutex(即quemutex队列长度最多为2)
int readcount = 0, writecount = 0;
Semaphore file = 1, rdcntmutex = 1, wrtcntmutex = 1;
Semaphore quemutex = 1, readEntry = 1;
Reader(){
  P(readEntry);
  	P(quemutex);			// 若有写者占用que,后续读者会被卡在外面
  		P(rdcntmutex);
  		if (readcount == 0) 
  				P(file);		// 若是第一个读者进来,则占据临界区阻止写进程写
  		readcount++;
  		V(rdcntmutex);
  	V(quemutex);
  V(readEntry);
  // 读操作不用互斥保护
  // reading operation
  // 读完了,读者走人
  P(rdcntmutex);
  	if (readcount == 1) 
  			V(file);		// 若是最后一个读者离开,则释放写进程的阻塞,允许写
  	readcount--;
  V(rdcntmutex);
}

Writer(){
  P(wrtcntmutex);
    if (writecount == 0)
        P(quemutex);	// 一旦写者进入,则占用该优先队列
  	writecount++;
  V(wrtcntmutex);
  P(file);	// 等待现存读者读完唤醒阻塞的写者
  	// writing, 写进程需要互斥保护
  V(file);
  P(wrtcntmutex);
    if (writecount == 1)
        V(quemutex);// 若源源不断有写者进入,writecount不会为0,也不会释放
  	writecount--;		// 当最后一个写者离开,才会唤醒等在que的一个读者
  V(wrtcntmutex);
}

猜你喜欢

转载自www.cnblogs.com/vanellopeblog/p/12785084.html