1. 问题描述
有读者和写者两组并发线程,共享一个数据库,当两个或以上的读线程同时访问共享数据时不会产生副作用,但若某个写线程和其他线程(读线程或写线程)同时访问共享数据时则可能导致数据不一致的错误。因此要求:
允许多个读者可以同时对文件执行读操作;
只允许一个写者往文件中写信息;
任一写者在完成写操作之前不允许其他读者或写者工作;
写者执行写操作前,应让已有的读者和写者全部退出。
也就是说,读进程不排斥其他读进程,而写进程需要排斥其他所有进程,包括读进程和写进程。
2. 问题分析
关系分析:由题目分析可知,读者和写者是互斥的,写者和写者也是互斥的,而读者和读者不存在互斥问题。
整理思路:写者是比较简单的,它与任何线程互斥,用互斥信号量的 PV 操作即可解决。读者的问题比较复杂,它必须实现与写者的互斥,多个读者还可以同时读。解决方案有两种:读写优先与写者优先。
读写优先:只要有一个读者处于活动状态(正在读),后来的读者即使比写者后到也会被接纳。如果读者源源不断地出现的话,那么写着就始终处于阻塞状态,直到所有读者读完为止。
写者优先:一旦写者就绪,那么写着会尽可能快地执行写操作。如果写者源源不断地出现的话,那么读者就始终处于阻塞状态。
3. 使用信号量实现
3.1 读者优先
读进程只要看到有其他读进程正在访问文件,就可以继续作读访问;写进程必须等待所有读进程都不访问时才能写文件,即使写进程可能比一些读进程更早提出申请。可以使用一个计数器rcount记录读者总数目(包含等待和正在读的数目),如果rcount大于0则写者等待,而读者直接读。当rcount==0写者与写者、写者与第一个读者抢占读写操作,这可以用一个二元信号量wt进行互斥访问。因为多个读者线程都要访问计数器,则使用一个二元信号量mutex进行互斥访问。
void writer
{
while(true)
{
P(wt);
write();
V(wt);
}
}
void reader()
{
while(true)
{
P(mutex) //对rcount进行互斥访问
rcount++;
if(rcount==1)
P(wt) //如果是第一个读者,与写者互斥抢占数据库
V(mutex)
read()
P(mutex) //对rcount进行互斥访问
rcout--;
if(rcount==0)
V(wt) //如果是最后一个读者,释放数据库所有权
V(mutex)
}
}<

最低0.47元/天 解锁文章
2987

被折叠的 条评论
为什么被折叠?



