您的位置:首页 > 其它

操作系统--信号量经典同步问题之读者优先问题

2016-12-19 10:28 225 查看
优先问题实际上是指用信号量来优先级抢占。这里读者优先有以下两个内涵:

1. 当读者线程正在访问临界区时,其他的读者线程可以优于写者线程访问临界区,只有所有的读者线程都执行完毕后,写者线程才能访问临界区。即实现读者优先。

2. 当写者线程正在访问临界区时,等待访问临界区的读者线程如何抢先于其他写者进程访问访问临界区,等到读者线程都执行完毕后,写者线程才能访问临界区。

有些教材认为读者优先只是实现第一点,因为如果实现第二点的话,当读者线程很多写者线程很少时,会造成写者线程处于饥饿状态。

以下是两种情况的伪代码:

 

int readCount; // readCount 是共享变量

semaphore  WriteMutex=1, CountMutex=1, x=1;

void Reader()

{

while(1)

{

sem_wait(CountMutex); // 信号量CountMutex用来实现互斥,即防止多个读者进程同时对readCount进行操作。

 readCount++;

if(readCount == 1) // 当readCount=1时,即此时没有其他读者进程在访问临界区,为了实现抢占应锁住写者线程。这样其他后来的进程可以直接去实现读操作,

写者线程只能等待。

sem_wait(WriteMutex);

sem_post(CountMutex);

read(); // 读取临界区数据

sem_wait(CountMutex) //同上

readCount --;

if(readCount == 0)

sem_post(WriteMutex)  // readCount=0时,表明此时所有的读者线程都执行完毕,释放锁,允许写者线程访问临界区。

sem_post(CountMutex)

}

}

void  Writer()

{

sem_wait(WriteMutex)

write() //向临界区写数据

sem_post(WriteMutex)

}

以上代码即可以实现上述第一点,即当读者线程访问临界区时,其他读者线程可以优于写者线程进行访问。只有当所有读者线程都执行完毕后,写者线程才能访问临界区。而当写者线程正在访问临界区时,读者线程无法实现抢占。

其实想要实现第二点只需在Writeer()中再加一对信号量即可。代码如下

void Writer()

{

sem_wait(x); //信号量X即用来实现第二点

sem_wait(WriteMutex) 

write() //向临界区写数据

sem_post(WriteMutex)

sem_post(x);

}

以上代码中,用信号量x来实现写者线程获得临界区资源时,读者线程优先于写者线程。 因为当写者线程获得临界区访问权时,其他的写者线程被信号量x阻塞。而读者线程则可以优先排在等待队列中,因此可以实现抢占线程。不过,如果有大量读者线程时,可能会造成写者线程饥饿现象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐