读者与写者的问题 (
来源:互联网 发布:加速度测试软件 编辑:程序博客网 时间:2024/06/05 00:01
读者与写者的问题
读者—写者问题(Readers-Writers problem)也是一个经典的并发程序设计问题,是经常出现的一种同步问题。计算机系统中的数据(文件、记录)常被多个进程共享,但其中某些进程可能只要求读数据(称为读者Reader);另一些进程则要求修改数据(称为写者Writer)。就共享数据而言,Reader和Writer是两组并发进程共享一组数据区,要求:
(1)允许多个读者同时执行读操作;
(2)不允许读者、写者同时操作;
(3)不允许多个写者同时操作。
Reader和Writer的同步问题分为读者优先、弱写者优先(公平竞争)和强写者优先三种情况,它们的处理方式不同。
(1)读者优先。对于读者优先,应满足下列条件:
如果新读者到:
①无读者、写者,新读者可以读;
②有写者等待,但有其它读者正在读,则新读者也可以读;
③有写者写,新读者等待。
如果新写者到:
①无读者,新写者可以写;
②有读者,新写者等待;
③有其它写者,新写者等待。
单纯使用信号量不能解决读者与写者问题,必须引入计数器rc 对读进程计数;rc_mutex 是用于对计数器rc 操作的互斥信号量;write表示是否允许写的信号量;于是读者优先的程序设计如下:
int rc=0;
semaphore rc_mutex=1;
semaphore write=1;
void reader()
do{
if (rc==1)
//若有,读进程等待,若无,阻塞写进程
if (rc == 0)
} while(1)
void writer()
do{
V(write);
读者优先的设计思想是读进程只要看到有其它读进程正在读,就可以继续进行读;写进程必须等待所有读进程都不读时才能写,即使写进程可能比一些读进程更早提出申请。该算法只要还有一个读者在活动,就允许后续的读者进来,该策略的结果是,如果有一个稳定的读者流存在,那么这些读者将在到达后被允许进入。而写者就始终被挂起,直到没有读者为止。
(2)写者优先1。为了解决以上问题,写者优先1的设计思想是在一个写者到达时如果有正在工作的读者,那么该写者只要等待正在工作的读者完成,而不必等候其后面到来的读者就可以进行写操作。注意,该算法当一个写者在等待时,后到达的读者是在写者之后被挂起,而不是立即允许进入。
在读者优先的算法的基础上增加了一个排队信号量read,读、写进程在每次操作前都要等待read信号量。写者优先1的程序设计如下:
int rc=0;
semaphore rc_mutex=1;
semaphore wc_mutex=1;
semaphore write=1;
semaphore read=1;
void reader()
do{
P(read);
P(rc_mutex);
rc++;
if rc=1 then
//读进程需要等待,若没有,阻塞写进程
V(rc_mutex);
V(read);
Reading the file;
P(rc_mutex);
rc--;
if rc=0 then
/
V(rc_mutex);
}
void
do{
P(read);
//到来的读进程排在该队列写者之后
P(write);
Writeing the file;
V(write);
V(read);
注意,该算法当第一个写者已经P(read)后,read变为0,来了N个读者,他们都停留在它的P(read)这一句。那么会出现什么问题呢?此时,如果原来的写者完成了,紧接又来了一个写者,写者需要P(read)。这个时候,由于N个读者都已经在这个写者之前P(read)了,所以这个写者需要排队排在这N个读者分别都得到P(read)后才能得到执行,这个就不是写者优先了,而是读者写者公平竞争。
(3)写者优先2。为了保证写者相对于读者的优先,需要提高写者进程的优先级。这里除增加一个排队信号量read,让读者和写者在读写之前都在此信号量上排队。还需增加一个信号量write_first,来保证写者优先。写者优先2的程序设计如下:
int rc, wc = 0;
semaphore read, write = 1;
semaphore rc_mutex, wc_mutex, write_first = 1;//用于读时、写时和写者优先的互斥
while(1){
P(rc_mutex);
//等待,若无,阻塞写进程
V(rc_mutex);
V(read);
V(write_first);
P(rc_mutex);
rc--;
if (rc==0) V(write);
V(rc_mutex);
}
void writer(){
while(1){
//阻塞,若无,阻塞新的读进程
V(write);
//进入,若有,唤醒一个读进程进入临界区
V(wc_mutex);
}
对于read信号量,每个读进程最开始都要申请一次,之后在真正做读操作前即让出,这使得写进程可以随时申请到 read。而写进程,只有第一个写进程需要申请 read,之后就一直占着不放了,直到所有写进程都完成后才让出。等于只要有写进程提出申请就禁止读进程在read信号量上排队。
假设一个写进程正在写时,接着后续有n个读者正在等待,这时又有一个新的写者要写,比较一下写者优先1和写者优先2的情况:写者优先1新来的写者需要等待n+1次V(read)操作,而写者优先2新来的写者只需等待2次V(read)操作,变相提高了写进程的优先级。
- 读者与写者的问题 (
- 读者与写者问题
- 读者与写者问题
- 读者与写者问题
- 读者写者问题--使用信号量的读者优先与写者优先程序分析
- 读者写者问题--使用信号量的读者优先与写者优先程序分析
- 读者与写者同步问题
- 操作系统之读者与写者问题
- 优先读者的读者/写者问题的算法设计
- 读者写者问题
- 读者写者问题
- 读者-写者问题
- 读者写者问题
- 读者写者问题
- 读者-写者问题
- 读者-写者问题
- 读者-写者问题
- 读者写者问题
- MySQL索引原理及慢查询优化
- STL --vector的介绍
- (转)关于FPGA器件的工作频率
- eclipse中JNI开发
- 在C#的类库中添加web service引用
- 读者与写者的问题 (
- Activity的生命周期总结
- 109.Examine the structure of the MARKS table:
- ubuntu技巧--minimal bash-like line editing
- 整理自己所学java基础内容,有错误的请大家指出,相互进步
- 开发中碰到的问题:Android应用程序打包时,出现错误:"XXX" is not translated in "af" (Afrikaans), "am" (Amharic), "ar" (Arab
- program g++ not found in path
- 数据库设计不求人(机房收费系统)
- R语言与非参数统计(核密度估计)