http://blog.sina.com.cn/s/blog_a3eacdb20101ct0c.html
问题的描述
有一个被许多进程共享的数据区,这个数据区可以是一个文件,或者主存的一块空间,甚至可以是一组处理器寄存器。有一些只读取这个数据区的进程(reader)和一些只往数据区中写数据的进程(writer)。以下假设共享数据区是文件。这些读者和写者对数据区的操作必须满足以下条件:读—读允许;读—写互斥;写—写互斥。这些条件具体来说就是:
(1)任意多的读进程可以同时读这个文件;
(2)一次只允许一个写进程往文件中写;
(3)如果一个写进程正在往文件中写,禁止任何读进程或写进程访问文件;
(4)写进程执行写操作前,应让已有的写者或读者全部退出。这说明当有读者在读文件时或者读者写文件不允许写者写文件。
明确2点:A.写者 和 任何读者或者任何写者都是互斥访问文件那个临界区
B.读者和写者互斥访问那个文件
(1)读者优先。对于读者优先,应满足下列条件:
如果新读者到:
①无读者、写者,新读者可以读;
②有写者等待,但有其它读者正在读,则新读者也可以读;
③有写者写,新读者等待。
如果新写者到:
①无读者,新写者可以写;
②有读者,新写者等待;
③有其它写者,新写者等待。
单纯使用信号量不能解决读者与写者问题,必须引入计数器count 对读进程计数;mutex 是用于对计数器count 操作的互斥信号量;
rw表示读者和写者互斥访问文件;于是读者优先的程序设计如下:
int count=0; //用于记录当前的读者数量 semaphore mutex=1; //用于对共享变量count操作的互斥信号量 semaphore rw=1; //用于保证读者和写者互斥访问那个文件的信号量 void reader() { while(1){ P(mutex); //开始对rc共享变量进行互斥访问 count++; //来了一个读进程,读进程数加1 if(rc==1) P(rw); //如是第一个读进程,判断是否有写进程在临界区, //若有读进程等待,若无可以读,阻塞写进程 V(mutex); //结束对count共享变量的互斥访问 读文件; P(mutex); //开始对count共享变量的互斥访问 count--; //一个读进程读完,读进程数减1 if(count == 0) V(rw);//允许写进程进行写 //最后一个离开临界区的读进程需要判断是否有写进 程 //需要进入临界区,若有,唤醒一个写进程进临界区 V(mutex); //结束对count共享变量的互斥访问 } } //写者进程,自己理解,好像简化了只有一个 void writer() while(1){ P(rw); //无读进程,进入写进程;若有读进程,写进程等待写文件;若有其他写进程拿走了 writing; V(rw); //写进程完成;判断是否有读进程需要进入临界区, //若有,唤醒一个读进程进临界区 }