本文共 2578 字,大约阅读时间需要 8 分钟。
注意这里为什么不用mutex,因为只能是对mutex加锁的线程对其解锁,其他线程不能解锁
读者优先算法:
设置两个互斥信号量:rwmutex 用于写者与其他读者/写者互斥的访问共享数据
rmutex 用于读者互斥的访问读者计数器readcountvar rwmutex, rmutex : semaphore := 1,1 ;
int readcount = 0; cobegin readeri begin // i=1,2,…. P(rmutex); Readcount++; If (readcount == 1) P(rwmutex);//当有第一个读者进入时,就对写信号加锁;则后续读者,直接读,不须判断是否有写进程 V(rmutex); 读数据; P(rmutex); Readcount--; If (readcount == 0) V(rwmutex);//当最后一个读者离开时,对写信号解锁 V(rmutex); End Writerj begin // j = 1,2,…. P(rwmutex);//只有当最后一个读者离开后,才能写 写更新; V(rwmutex); End Coend写者优先:
条件:
1)多个读者可以同时进行读 2)写者必须互斥(只允许一个写者写,也不能读者写者同时进行) 3)写者优先于读者(一旦有写者,则后续读者必须等待,唤醒时优先考虑写者)
解1:如果读者数是固定的,我们可采用下面的算法:
rwmutex:用于写者与其他读者/写者互斥的访问共享数据
rmutex: 该信号量初始值设为10,表示最多允许10个读者进程同时进行读操作var rwmutex, rmutex : semaphore := 1,10 ;
cobegin readeri begin // i=1,2,…. P(rwmutex); //读者、写者互斥 P(rmutex); V(rwmutex); // 释放读写互斥信号量,允许其它读、写进程访问资源 读数据; V(rmutex); EndWriterj begin // j = 1,2,….
P(rwmutex); For (i=1;i<=10;i++) P(rmutex); //禁止新读者,并等待已进入的读者退出 写更新; For (i=1;i<=10;i++) V(rmutex); // 恢复允许rmutex 值为10 V(rwmutex); End Coend
解2:如果读者数不固定,采用下面的算法:
设置三个互斥信号量:rwmutex 用于写者与其他读者/写者互斥的访问共享数据
rmutex 用于读者互斥的访问读者计数器readcount nrmutex 用于写者等待已进入读者退出,所有读者退出前互斥写操作var rwmutex, rmutex,nrmutex : semaphore := 1,1,1 ;
int readcount = 0; cobegin readeri begin // i=1,2,…. P(rwmutex); // 写进程优先,一旦有写的进程,就不再允许有读的进程再加入了 P(rmutex); Readcount++; If (readcount == 1) P(nrmutex); //有读者进入,互斥写操作//nrmutex用来判断是否还有读者 V(rmutex); V(rwmutex); // 及时释放读写互斥信号量,允许其它读、写进程申请资源 读数据; P(rmutex); Readcount--; If (readcount == 0) V(nrmutex); //所有读者退出,允许写更新 V(rmutex); EndWriterj begin // j = 1,2,….
P(rwmutex); // 互斥后续其它读者、写者 P(nrmutex); //如有读者正在读,等待所有读者读完 写更新; V(nrmutex); //允许后续新的第一个读者进入后互斥写操作 V(rwmutex); //允许后续新读者及其它写者 End Coend//读写进程, 读者优先。即使有写进程在等待,新进的读进程也直接进入//由读进程控制wsem_t mutex = 1, w = 1;int count = 0;void reader() { while (1) { p(mutex); if (count == 0) p(w); ++count; v(mutex); //reading.... p(mutex); --count; if(count == 0) v(w); v(mutex); }}void writer() { while (1) { p(w); //writing v(w); }}//写优先只需要用写线程控制读的信号量r, 也就是在writer和reader的开始和结束添加pv操作//在有写进程等待时,就不会有新的读进程进入sem_t mutex = 1, w = 1, r = 1;int count = 0;void reader() { while (1) { p(r); p(mutex); if (count == 0) p(w); ++count; v(mutex); v(r); //reading.... p(mutex); --count; if(count == 0) v(w); v(mutex); }}void writer() { while (1) { p(r); p(w); //writing v(w); v(r); }}
转载地址:http://yseti.baihongyu.com/