读写互斥,写写互斥,读读可并发并发
信号量:w=1(可写),mutex=1(可读)
共享变量:rcount=0(读者数量)spa
//伪代码 int rcount=0 semaphore w=1,mutex=1 reader(){ P(mutex); rcount++; if(rcount==1) P(w);//堵塞写者,保证全部读者读完 V(mutex); //以上保证全部读者均可同时读 //Read() P(mutex); rcount--; if(rcount==0) V(w); V(mutex); } writer(){ P(w); //write() V(w); }
存在问题,读者过多,饿死写者(rcount减小同时也在增长)。.net
增长wcount标记写者存在,若是同时存在读写者,读者在执行时经过P(w)阻塞写者,而写者wcount标记存在,经过P(r)防止读者继续加入。code
P(x)与V(x)用以保护原子操做blog
int wcount=0,rcount=0; semaphore w=1,r=1,x=1; reader(){ P(r); P(x); rcount++; if(rcount==1) P(w); V(x); V(r); //Read() P(x); rcount--; if(rcount==0) V(w); V(x); } writer(){ P(x); wcount++; if(wcount==1) P(r); V(x); P(w); //Write() V(w); P(x); wcount--; if(wcount==0) V(r); V(x); }
进程同步的经典问题1——读者写者问题(写者优先与公平竞争)
能够参考,这是代码进程
semaphore fmutex=1, rdcntmutex=1, wtcntmutex=1, queue=1; //fmutex --> access to file; rdcntmutex --> access to readcount //wtcntmutex --> access to writecount int readcount = 0, writecount = 0; void reader(){ while(1){ wait(queue); wait(rdcntmutex); if(0 == readcount)wait(fmutex); readcount = readcount + 1; signal(rdcntmutex); signal(queue); //Do read operation ... wait(rdcntmutex); readcount = readcount - 1; if(0 == readcount)signal(fmutex); signal(rdcntmutex); } } void writer(){ while(1){ wait(wtcntmutex); if(0 == writecount)wait(queue); writecount = writecount + 1; signal(wtcntmutex); wait(fmutex); //Do write operation ... signal(fmutex); wait(wtcntmutex); writecount = writecount - 1; if(0 == writecount)signal(queue); signal(wtcntmutex); } }
增长一个排队信号量:queue。读写进程访问文件前都要在此信号量上排队,经过区别对待读写进程即可达到提升写进程优先级的目的。另外再增长一个 writecount 以记录提出写访问申请和正在写的进程总数.
每一个读进程最开始都要申请一下 queue 信号量,以后在真正作读操做前即让出(使得写进程能够随时申请到 queue)。而只有第一个写进程须要申请 queue,以后就一直占着不放了,直到全部写进程都完成后才让出。等于只要有写进程提出申请就禁止读进程排队,变相提升了写进程的优先级。 get