读者写者问题是操作系统中经典的互斥问题:一块数据被多个读者和写者的访问,需要考虑读写互斥、写写互斥(可以同时由多个读者读取)。具体的又可以分为读者优先和写者优先两类。
读者优先算法:
当新的读者到来的时候,若当前正有读者在进行读操作,则该读者无需等待前面的写操作完成,直接进行读操作。
设置两个互斥信号量:
l rwmutex 用于写者与其他读者/写者互斥的访问共享数据
l rmutex 用于读者互斥的访问读者计数器readcount
var rwmutex, rmutex : semaphore := 1,1;
int readcount = 0;
Cobegin
Readeri begin //i=1,2,….
P(rmutex);
If (readcount == 0)
P(rwmutex);
readcount++;
V(rmutex);
读共享数据;
P(rmutex);
readcount--;
If (readcount == 0)
V(rwmutex);
V(rmutex);
End
Writerj begin // j = 1,2,….
P(rwmutex);
写共享数据;
V(rwmutex);
End
Coend
写者优先:
1)多个读者可以同时进行读
2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行)
3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
设置三个互斥信号量:
l rwmutex 用于写者与其他读者/写者互斥的访问共享数据
l rmutex 用于读者互斥的访问读者计数器readcount
l nrmutex 用于写者等待已进入读者退出,所有读者退出前互斥写操作
var rwmutex, rmutex,nrmutex : semaphore := 1,1,1;
int readcount = 0;
Cobegin
Readeri begin //i=1,2,….
P(rwmutex);
P(rmutex);
If (readcount == 0)
P(nrmutex); //有读者进入,互斥写操作
readcount++;
V(rmutex);
V(rwmutex); // 及时释放读写互斥信号量,允许其它读、写进程申请资源、
读共享数据;
P(rmutex);
readcount--;
If (readcount == 0)
V(nrmutex); //所有读者退出,允许写更新
V(rmutex);
End
Writerj begin // j = 1,2,….
P(rwmutex); // 互斥后续其它读者、写者
P(nrmutex); //如有读者正在读,等待所有读者读完
写共享数据;
V(nrmutex); //允许后续新的第一个读者进入后互斥写操作
V(rwmutex); //允许后续新读者及其它写者
End
Coend