【问题标题】:Second readers-writers pr*blem - why is third mutex needed at reader第二个读者 - 作家 pr*blem - 为什么读者需要第三个互斥锁
【发布时间】:2014-02-05 11:11:25
【问题描述】:

我不明白在第二个读写器问题的通用解决方案中,在读取器程序最开始时最外层互斥锁的目的是什么。

为了说明这一点,我将从适当的维基百科条目 (link) 中发布代码。我说的是 mutex_3 :

READER
  P(mutex_3);
    P(r);
      P(mutex_1);
        readcount := readcount + 1;
        if readcount = 1 then P(w);
      V(mutex_1);
    V(r);
  V(mutex_3);

  reading is performed

  P(mutex_1);
    readcount := readcount - 1;
    if readcount = 0 then V(w);
  V(mutex_1);

我能想到的唯一答案是阻止新读者的涌入。但我认为,除了它的核心功能之外,下一个互斥体 r 已经完成了。我错了吗?

【问题讨论】:

    标签: concurrency semaphore theory


    【解决方案1】:

    我看到不久前有人问过这个问题,但我想我还是会发布答案,以防将来对其他人有所帮助。

    我们使用互斥锁来保护共享资源不被多个线程同时访问。在 mutex_3 的情况下,如果您查看紧跟在 P(mutex_3) 之后的代码,我们会看到我们要保护的共享资源是信号量 r。因此,拥有 mutex_3 可确保在任何时候只有一个阅读器可以执行 P(r) 和 V(r) 之间的代码段。

    要了解为什么这个互斥锁很重要,我们还需要考虑编写器的代码。来自维基百科:

    作家

    P(mutex_2);
     writecount := writecount + 1;
     if writecount = 1 then **P(r)**;  <-- Writer waits on semaphore r
    V(mutex_2);
    
    P(w);
     writing is performed
    V(w);
    
    P(mutex_2);
     writecount := writecount - 1;
     if writecount = 0 then V(r);
    V(mutex_2);
    

    要注意的关键部分以粗体显示。如您所见,作者和读者都在信号量 r 上调用 P(r)。在这种情况下,不清楚谁的调用首先成功。我们假设 writer 在调用 P(r) 时没有任何优先级(如果有,则不需要 mutex_3)。

    但是,第二个读者-作者问题的问题陈述指出,作者应该尽快开始。如果调度发生在先到先服务的基础上,那么在上述情况下,如果读取器设法首先调用 P(r),则读取器的调用成功。然后作者被延迟,这是我们不希望的。

    因此,解决方案是在阅读器 (mutex_3) 的设置代码周围放置一个互斥锁。现在,当一个读取器调用 V(r) 时,不能有任何其他读取器在 r 上等待,因为其他读取器需要获取 mutex_3 才能调用 P(r),但当前读取器持有 mutex_3!然而,可能有一个写入者在等待 r,因此在这种情况下,写入者对 P(r) 的调用总是尽快成功,因为它是唯一一个等待 r 的写入者。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-18
      • 1970-01-01
      • 2014-03-26
      • 1970-01-01
      • 1970-01-01
      • 2017-11-03
      • 2018-02-15
      • 1970-01-01
      相关资源
      最近更新 更多