操作系统学习笔记——读者写者问题
程序员文章站
2022-07-04 23:34:44
...
动机:共享数据的访问
两种类型使用者:读者,不需要修改数据;写者,读取和修改数据
问题的约束:
允许同一时间有多个读者,但在任何时候只有一个写者;当没有写者时,读者才能访问数据;当没有读者和写者时,写者才能访问数据;在任何时候只能有一个线程可以操作共享变量。
多个并发进程的数据集共享:读者-只读数据集;他们不执行任何更新。写者 - 可以读取和写入
共享数据: 数据集data;信号量CountMutex,保证Rcount的互斥,初始化为1;信号量WriteMutex,对写者的互斥保护,初始化为1;整数Rcount代表多少个读者,初始化为0
信号量实现,读者优先:
写者
sem_wait(WriteMutex);
write;
sem_post(WriteMutex);
读者
sem_wait(CountMutex); 对Rcount做互斥保护
if(Rcount == 0)
sem_wait(WriteMutex); //将read包起来
++Rcount;
sem_post(CountMutex); 所以这一句和上面的那句包起来中间的部分
read;
sem_wait(CountMutex); 对Rcount做互斥保护
--Rcount;
if(Rcount==0)
sem_post(WriteMutex); //将read包起来
sem_post(CountMutex); 所以这一句和上面的那句包起来中间的部分
用管程实现写者优先:
伪码:
Database::Read(){
Wait until no writers;
read database;
check our - wake up waiting writers;
}
Database::Write(){
Wait until no readers/writes;
write database;
check out - wake up waiting readers/writers;
}
管程的状态变量:
AR = 0; //活动的读者
AW = 0; //活动的写者
WR = 0; //等待的读者
WW = 0; //等待的写者
Condition okToRead;//两个条件变量
Condition okToWrite;
Lock lock; //互斥
读者的实现:
Public Database::Read(){
//wait until no writers;
StartRead();
read database;
//check out - wake up waiting writers;
DoneRead();
}
Private Database::StartRead(){
lock.Acquire();//确保只有一个函数进入管程
while( (AW+WW)>0 ){//存在写者
WR++;
okToRead.wait(&lock);//去等待,释放锁
WR--;
}
AR++;//读者增加一个
lock.Release();
}
Private Database::DoneRead(){
lock.Acquire();
AR--; //读完后读者减1
if( AR==0 && WW>0 ){
okToWrite.signal();//唤醒写者
}
lock.Release();
}
写者:
Public Database::Write(){
//wait until no readers/writers;
StartWrite();
write databse;
//check out - wake up waiting readers/writers;
DoneWrite();
}
Private Database::StartWrite(){
lock.Acquire();
while( (AW+AR)>0 ){
WW++;
okToWrite.wait(&lock);
WW--;
}
AW++;
lock.Release();
}
Private Database::DoneWrite(){
lock.Acquire();
AW--;
if(WW>0){
okToWrite.signal();//唤醒一个写者
}
else if(WR>0){
okToRead.broadcast();//唤醒所有等待的读者
}
lock.Release();
}
上一篇: 操作系统 读者写者同步问题
下一篇: 操作系统读者写者问题