有两组并发进程:读者和写者,共享一个文件F
读者可以同时读取文件
读者和写者不能同时对文件进行操作
两个读者也不能同时对文件进行操作
读者优先模型:
读者不释放写者的临界区资源,写者就不能进行操作
int readcount=0;//读进程计数 semaphore writeblock,mutex;//信号量 writeblock=1;//写者在进入和退出使用的临界资源 mutex=1; //读者者在进入和退出使用的临界资源 ,保证readcount的唯一变化 //读者进程 process reader_i( ){ P(mutex); //上锁,读者-读者互斥 readcount++; //PV保证readcout唯一变化 if(readcount==1) //当有一个读者时,不允许写者进行操作 P(writeblock);//上锁,实现读者-写者互斥 V(mutex); //解锁,释放读者临界区资源 {读文件}; P(mutex);//上锁,读者-读者互斥 readcount--; if(readcount==0)//当读者全部退出,则释放写者的临界区 V(writeblock); //解锁,释放写者临界区 V(mutex); //解锁,释放读者临界区资源 } //写者进程 process writer_j( ){ P(writeblock);//上锁,临界区资源(写者-写者互斥) {写文件}; V(writeblock); }
写者优先模型:
Entemutex是为了保证写者可以在读者退出Quemutex临界区是第一时间抢占,并且当写者队列还有人的时候不释放
int readcount;//读者数量 int writecount;//写者数量 semaphore Entemutex,Quemutex,fmutex,Wcount,Rcount;//信号量 Entemutex=1;//避免写者与读者之间竞争 Quemutex=1;//读者和写者在进入和退出使用的临界资源 (保证只读或只写) fmutex=1;//写者的临界区 Wcount=1;//写者在进入和退出使用的临界资源 Rcount=1;//读者者在进入和退出使用的临界资源 ,保证readcount的唯一变化 //读者线程 Reader() { while(1) { P(Entemutex);//避免写者同时与多个读者竞争 P(Quemutex);//申请门口临界区 (读-写互斥信号) P(Rcount);//读者-读者互斥,上锁 readcount ++; if(readcount == 1)//第一个读者进入,上锁(读者-写者互斥) P(fmutex);//上锁,不允许写者进入 V(Rcount);//解锁 V(Quemutex);//读-写解锁 ,当Quemutex释放,写者可以抢占该临界区 (写者抢占后,后续读者在也进不去,直到写者释放资源) //后续读者只能不断的退出,当读者退出完毕,释放fmutex,写者进入 V(Entemutex); {读文件} P(Rcount);//读者退出 readcount--; if(readcount == 0)//解锁 V(fmutex);//允许写者进入 V(Rcount);//解锁读者-读者 } } //写者线程 writer() { while(1) { P(Wcount);//上锁,进入临界区 (写者进门) writecount ++; if(writecount == 1)//第一个写者进入,上锁 P(Quemutex);//有读者的时候,滞留于此,当读者一旦释放,则抢占。 V(Wcount);//解锁 P(fmutex);//上锁,写者-写者互斥 {写文件} V(fmtex);//操作完成,解锁 P(Wcount);//退出,进入临界区 (写者出门) writecount-- ; if(readcount == 0) //当写者为0时,释放临界区给读者使用 V(Quemutex);//只要writecount不为0就不是放,写者优先 V(Wcount);//解锁 } }
公平竞争:
semaphore writeblock,mutex;//信号量 int readcount;//读者数量 Quemutex=1;//读者和写者进入和退出使用的临界资源 Rcount=1;//读者在进入和退出使用的临界资源 fmutex=1;//写者在进入和退出使用的临界资源 Reader() { while(1) { P(Quemutex);//上锁,读者-写者互斥 P(Rcount);//上锁,读者-读者互斥 readcount ++; if(readcount == 1) P(fmutex);//上锁,不允许写者进入 V(Rcount);//解锁 V(Quemutex);//解锁 {读文件} P(Rcount);//上锁,读者-读者互斥 if(readcount == 0) V(fmutex);//解锁,允许读者进入 V(Rcount);//解锁 } } writer() { while(1) { P(Quemutex);//上锁,读者-写者互斥 P(fmutex);//上锁,写者-写者互斥 {写文件} V(fmtex);//解锁 V(Qmutex);//解锁 } }