Concurrency 读者-作者-作者优先级问题 问题

Concurrency 读者-作者-作者优先级问题 问题,concurrency,semaphore,Concurrency,Semaphore,在《信号灯小书》一书中,p。71,存在以下问题: 写一个读者-作者问题的解决方案,优先考虑作者。也就是说,一旦写入程序到达,在所有写入程序离开系统之前,不应允许任何读卡器进入 我得出了一个解决方案,但它与书中给出的有点不同 我的解决方案 共享变量: readSwitch = Lightswitch() writeSwitch = Lightswitch() noWriters = Semaphore(1) noReaders = Semaphore(1) noReaders.wait() no

在《信号灯小书》一书中,p。71,存在以下问题:

写一个读者-作者问题的解决方案,优先考虑作者。也就是说,一旦写入程序到达,在所有写入程序离开系统之前,不应允许任何读卡器进入

我得出了一个解决方案,但它与书中给出的有点不同

我的解决方案 共享变量

readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
noReaders.signal()

readSwitch.lock(noWriters)

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

writeSwitch.unlock(noReaders)
noWriters.signal()
readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
readSwitch.lock(noWriters)
noReaders.signal()

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

noWriters.signal()
writeSwitch.unlock(noReaders)
Semaphore(1)
表示初始化为1的信号量,而
Lightswitch
在本书中的定义如下:

class Lightswitch:
  def __init__(self):
    self.counter = 0
    self.mutex = Semaphore(1)

  def lock(self, semaphore):
    self.mutex.wait()
    self.counter += 1
    if self.counter == 1:
      semaphore.wait()
    self.mutex.signal()

  def unlock(self, semaphore):
    self.mutex.wait()
    self.counter -= 1
    if self.counter == 0:
      semaphore.signal()
    self.mutex.signal()
读卡器逻辑

readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
noReaders.signal()

readSwitch.lock(noWriters)

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

writeSwitch.unlock(noReaders)
noWriters.signal()
readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
readSwitch.lock(noWriters)
noReaders.signal()

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

noWriters.signal()
writeSwitch.unlock(noReaders)
编写器逻辑

readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
noReaders.signal()

readSwitch.lock(noWriters)

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

writeSwitch.unlock(noReaders)
noWriters.signal()
readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
readSwitch.lock(noWriters)
noReaders.signal()

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

noWriters.signal()
writeSwitch.unlock(noReaders)
书的解决方案 共享变量

readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
noReaders.signal()

readSwitch.lock(noWriters)

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

writeSwitch.unlock(noReaders)
noWriters.signal()
readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
readSwitch.lock(noWriters)
noReaders.signal()

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

noWriters.signal()
writeSwitch.unlock(noReaders)
读卡器逻辑

readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
noReaders.signal()

readSwitch.lock(noWriters)

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

writeSwitch.unlock(noReaders)
noWriters.signal()
readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
readSwitch.lock(noWriters)
noReaders.signal()

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

noWriters.signal()
writeSwitch.unlock(noReaders)
编写器逻辑

readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
noReaders.signal()

readSwitch.lock(noWriters)

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

writeSwitch.unlock(noReaders)
noWriters.signal()
readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
noReaders.wait()
readSwitch.lock(noWriters)
noReaders.signal()

# critical section for readers

readSwitch.unlock(noWriters)
writeSwitch.lock(noReaders)
noWriters.wait()

# critical section for writers

noWriters.signal()
writeSwitch.unlock(noReaders)
问题 1) 在读卡器逻辑中,在我的解决方案中,
noReaders.signal()
紧接着
noReaders.wait()
。这里的想法是,
noReaders
就像一种旋转栅门,允许读者通过,但一到就被作者锁定

但是,在本书的解决方案中,
noReaders.signal()
是在调用
readSwitch.lock(noWriters)
之后完成的

我的订购会产生不正确的行为,有什么原因吗

2) 在writer逻辑中,在我的解决方案中,
writeSwitch.unlock(noReaders)
位于
noWriters.signal()之前。然而,这本书把它们放在了相反的顺序。我的订购会产生不正确的行为,有什么原因吗

编辑:补充问题 我还有一个问题。我可能对这本书的解决方案有些误解。假设发生以下情况:

  • 读卡器1获取
    noReaders
    noReaders
    变为0)

  • 读卡器2在
    noReaders
    中等待(
    noReaders
    变为-1)

  • 写入程序1在
    noReaders
    中等待(
    noReaders
    变为-2)

  • 读卡器3在
    noReaders
    中等待(
    noReaders
    变为-3)

  • 读卡器4在
    noReaders
    中等待(
    noReaders
    变为-4)

  • 读取器1获取
    noWriters
    noWriters
    变为0)

  • 读卡器1发出信号
    noReaders
    noReaders
    变为-3;读卡器2解锁)

  • 读卡器2通过
    noWriters
    lightswitch;信号
    noReaders
    noReaders
    变为-2, 读卡器3(未被阻止)

在上述情况下,似乎更多的读者可以继续到达并进入关键部分,尽管作者正在等待

此外,考虑到读写器正在循环,完成关键部分的读写器可以循环并再次等待
noReaders
,即使已经有写写写器在等待


我在这里误解了什么?

根据您的解决方案,以下情况是可能的:

  • 新的写入程序出现在
    writeSwitch.unlock(noReaders)
    之后,但在
    noWriters.signal()之前
  • 新写入程序执行
    writeSwitch.lock(noReaders)
  • 读卡器执行
    readSwitch.lock(noWriters)
    ,即使有编写器也会进入关键部分

这本书的解决方案首先唤醒了等待的作家,然后才唤醒了读者。您的解决方案首先唤醒读卡器,还允许读卡器在
readSwitch.lock(noWriters)
处排队,这样即使有写入程序在等待,它们也可以运行。

使用您的解决方案,可能出现以下情况:

  • 新的写入程序出现在
    writeSwitch.unlock(noReaders)
    之后,但在
    noWriters.signal()之前
  • 新写入程序执行
    writeSwitch.lock(noReaders)
  • 读卡器执行
    readSwitch.lock(noWriters)
    ,即使有编写器也会进入关键部分

这本书的解决方案首先唤醒了等待的作家,然后才唤醒了读者。您的解决方案首先唤醒读者,还允许读者在
readSwitch.lock(noWriters)
处排队,这样即使有写入程序等待,他们也可以运行。

谢谢。我同意,在writer中,我的解决方案中最后两行的顺序应该颠倒:writer应该在解锁
noReaders
之前发出信号
noWriters
,以便它优先处理等待的writer。然而,我仍然不清楚为什么我的解决方案读取器的前两行顺序错误。我还添加了一个“编辑:附加问题”部分,带有附加疑问。感谢您的耐心。对于您问题的新增内容:请注意,读者处于关键部分,没有
noReaders
lock。因此,一旦读卡器进入其关键部分,写卡器就可以对
noReaders
执行锁定,从而阻止其他读卡器。诚然,当发生这种情况时,其他读者可以进入,但读者必须遵守规范:一旦一个作者到达,所有的作者都必须被处理。它并不是说一个作者到达就必须被允许。您的读者解决方案,带有锁定/解锁功能,允许读者在
readSwitch.lock(noWriters)
处排队。因此,当一位作者完成并发布了《noWriters》(《代码》)时,即使有新的作者,读者也可能会参与进来。现在看来,这一点已经清楚多了。读取器获取
noReaders
后,必须先锁定
noWriters
,然后再发信号通知
noReaders
。否则,读卡器可以执行
readSwitch.lock(noWriters)
,并在编写器发出信号
noWriters
时进入关键部分,即使还有其他编写器在等待。谢谢。我同意,在writer中,我的解决方案中最后两行的顺序应该颠倒:writer应该在解锁
n之前发出信号
noWriters