使用监视器的读写器解决方案

先决条件—— 进程同步 , 监视器 , 读者作家问题 考虑到共享数据库,我们的目标是:

null
  • 只有在没有写入程序的情况下,读卡器才能访问数据库。
  • 只有在没有读卡器或写卡器的情况下,写卡器才能访问数据库。
  • 一次只有一个线程可以操作状态变量。

解决方案的基本结构——

Reader()
   Wait until no writers
   Access database
   Check out – wake up a waiting writer
Writer()
   Wait until no active readers or writers
   Access database
   Check out – wake up waiting readers or writer

–现在让我们假设一位作家是活跃的,读者和作家的混合体现在出现了。 下一个应该是谁? ——或者假设一位作家正在等待,无数读者不断出现。 对他们来说变得活跃公平吗? 因此,我们将实施一种来回形式的公平:

  • 一旦有读者在等待,下一位读者就会进入。
  • 如果一位作家正在等待,下一位作家将进入。

使用监控器实施解决方案:-

  1. 这些方法应该以互斥方式执行,即在每个时间点,最多一个线程可以执行其任何方法。
  2. 监视器还为线程提供了一种机制,使其在重新获得独占访问并恢复其任务之前,暂时放弃独占访问,以等待满足某些条件。
  3. 监视器还有一种机制,用于向其他线程发出信号,表明这些条件已经满足。
  4. 所以在这个实现中,仅仅相互排斥是不够的。尝试操作的线程可能需要等待,直到某个断言P为真。
  5. 当一个线程正在等待一个条件变量时,该线程不会被认为占用监视器,因此其他线程可能会进入监视器以更改监视器的状态。

代码–

// STATE VARIABLES
// Number of active readers; initially = 0
int NReaders = 0;
// Number of waiting readers; initially = 0
int WaitingReaders = 0;
// Number of active writers; initially = 0
int NWriters = 0;
// Number of waiting writers; initially = 0
int WaitingWriters = 0;
Condition canRead = NULL;
Condition canWrite = NULL;
Void BeginWrite()
{
// A writer can enter if there are no other
// active writers and no readers are waiting
if (NWriters == 1 || NReaders > 0) {
++WaitingWriters;
wait(CanWrite);
--WaitingWriters;
}
NWriters = 1;
}
Void EndWrite()
{
NWriters = 0;
// Checks to see if any readers are waiting
if (WaitingReaders)
Signal(CanRead);
else
Signal(CanWrite);
}
Void BeginRead()
{
// A reader can enter if there are no writers
// active or waiting, so we can have
// many readers active all at once
if (NWriters == 1 || WaitingWriters > 0) {
++WaitingReaders;
// Otherwise, a reader waits (maybe many do)
Wait(CanRead);
--WaitingReaders;
}
++NReaders;
Signal(CanRead);
}
Void EndRead()
{
// When a reader finishes, if it was the last reader,
// it lets a writer in (if any is there).
if (--NReaders == 0)
Signal(CanWrite);
}


了解解决方案:-

  • 它想要公平。

  1. 如果作者正在等待,读者就会排队。
  2. 如果读卡器(或另一个写卡器)处于活动状态或正在等待,写卡器将排队。
  3. 这在很大程度上是公平的,尽管一旦它让一个读者进来,它就让所有等待的读者同时进来,即使有些读者在其他等待的作者之后出现。

  • 代码是“简化的”,因为我们知道一次只能有一个编写器。

  • 它还利用了这样一个事实,即如果没有人等待,信号是不可操作的。

    1. 在“EndWrite”代码中(它表示可以在不检查等待写入程序的情况下写入)
    2. 在EndRead代码中(同样的事情)
    3. 在StartRead中(信号可以在末尾读取)

    对于信号量,我们从未有过这种“公平”的解决方案。事实上,这是可以做到的,但代码是相当棘手的。在这里,简单的解决方案以理想的方式工作!监视器不太容易出错,也更容易理解。

  • © 版权声明
    THE END
    喜欢就支持一下吧
    点赞5 分享