一个数据文件或记录可以为多个并发进程所共享。称之需要读该文件或记录的进程为“读者进程”,而更新数据文件中的数据或修改数据的进程为“写者进程”。
读者--写者,写着--读者,写者--写着之间都存在互斥。
解决读者--写者问题一共存在三种方式:
(1,读者优先;(这种情况会存在活锁现象,由于读者的不断读取与增多,会使写者一直处于饥饿状态)
(2,读写公平;(读者与写着按访问的顺序来访问数据库)
(3,写者优先;(会存在与(1,类似的情况)
P--V语句
(1,读者优先:
信号量定义
readcount 共享型整型变量,记录正在读取数据的读者数目,初值为0;
mutex 用于使读者互斥的访问共享变量readcount,初值为1;
wrt 用于实现写者与读者以及写着与写者对共享数据区的互斥访问,初值为1.
读者循环
p(mutex); //取得对readcount共享变量的控制权;
readcount=readcount+1; // 读者进入数据文件区,人数+1;
if(readcount==1) //判断是否为第一个到达的读者;
p(wrt); //申请共享数据区的控制权;
v(mutex); //释放对readcount共享变量的控制权;
读取数据文件;
p(mutex);
readcount=reacount-1; //读者读取数据完成,人数-1;
if(readcount==0) //判断是否为最后一个离开数据区的读者;
v(wrt); //释放共享数据区的控制权;
v(mutex);
第一个读者到达数据区后,如果又有多个读者访问,那么除第一个读者外,其他读者不用申请对数据区的控制权,直接读取数据就可,而且只要读者不是最后一个,读取完数据,可以直接离开数据区。
只有所有读者全部读取完成,写者才可获得对p(wrt)的控制权。
写者循环
p(wrt);
更新数据库;
v(wrt);
(2,读写公平:
增设一个变量w,初值为1(w变量是对于读者,写者进入数据区的控制及排序)
写者循环
p(w);
p(wrt);
更新数据;
v(wrt);
v(w);
读者循环
p(w); //申请入门资格
p(mutex); //取得对readcount共享变量的控制权;
readcount=readcount+1; // 读者进入数据文件区,人数+1;
if(readcount==1) //判断是否为第一个到达的读者;
p(wrt); //申请共享数据区的控制权;
v(mutex); //释放对readcount共享变量的控制权;
v(w); //释放一个入门资格;
读取数据文件;
p(mutex);
readcount=reacount-1; //读者读取数据完成,人数-1;
if(readcount==0) //判断是否为最后一个离开数据区的读者;
v(wrt); //释放共享数据区的控制权;
v(mutex);
(3,写者优先:
增设变量 R ,初值为1;
p(R);
p(mutex); //取得对readcount共享变量的控制权;
readcount=readcount+1; // 读者进入数据文件区,人数+1;
if(readcount==1) //判断是否为第一个到达的读者;
p(wrt); //申请共享数据区的控制权;
v(mutex); //释放对readcount共享变量的控制权;
v(R);
读取数据文件;
p(mutex);
readcount=reacount-1; //读者读取数据完成,人数-1;
if(readcount==0) //判断是否为最后一个离开数据区的读者;
v(wrt); //释放共享数据区的控制权;
v(mutex);
写者循环:
p(mutex);
writecount=writecount+1;
if(writecount==1)
p(R);
v(mutex);
p(wrt);
更新数据文件;
v(wrt);
p(mutex);
writecount=writecount-1;
if(writecount==0)
v(R) ;
v(mutex);
只要写者循环获得了对R的控制权,读者进程会一直被阻塞的,直到所有写者对数据库的操作完成。
不爱吃香菜也可做香菜头子,人生也是这样的。