在《信号灯小书》一书中,第71页,存在以下问题:
写一个读者-作者问题的解决方案,优先考虑作者。也就是说,一旦写入程序到达,在所有写入程序离开系统之前,不应允许任何读卡器进入。
我得出了一个解决方案,但它与书中给出的有点不同。
共享变量:
readSwitch = Lightswitch()
writeSwitch = Lightswitch()
noWriters = Semaphore(1)
noReaders = Semaphore(1)
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()
读卡器逻辑:
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。信号()
紧跟在noReaders之后。等待()
。这里的想法是,noReaders
就像一种旋转栅门,允许读者通过,但一到就被作者锁定。
然而,在这本书的解决方案中,noReaders。调用
readSwitch后完成signal()
。。
我的订购会产生不正确的行为,有什么原因吗?
2)在编写逻辑中,在我的解决方案中,
写witch.unlock(noReaders)
在noWriters.signal()
之前。然而,这本书把它们放在相反的顺序。我的订购会产生不正确的行为,有什么原因吗?
我还有一个问题。我可能对这本书的解决方案有些误解。假设发生以下情况:
>
读卡器1获取
noReaders
(noReaders
变为0)
读卡器2在
noReaders
中等待(noReaders
变为-1)
写入程序1在
noReaders
中等待(noReaders
变为-2)
读卡器3在
noReaders
中等待(noReaders
变为-3)
Reader 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()
写witch.lock(noReaders)
这本书的解决方案首先唤醒了等待的作家,然后才唤醒了读者。您的解决方案首先唤醒读卡器,还允许读卡器在readSwitch处排队。锁定(noWriters)
,这样即使有写入程序在等待,它们也可以运行。
维基百科上说,下面的代码“增加了不允许任何线程饿死的限制”,我不明白为什么没有饿死。例如:如果有很多作者在任何读者之前到达,并且第一个作者花了很长时间完成他的写作,那么r可能会达到一些大的负数,比如说-12345,然后读者开始与作者一起到达,不知怎的,操作系统总是选择writer来接收信号量,而不是reader,如果那样的话,读者会挨饿,这是对的还是我错了?链接:读者和作者问题 请看链接中的第三个
本书英文版原作者是 Michael Hartl,把 Ruby on Rails Web 开发介绍给世人的先行者之一,也是自出版平台 SoftCover 的联合创始人。他之前曾经写作并开发了 RailsSpace,一本很过时的 Rails 教程;也曾使用 Ruby on Rails 开发过一个名为 Insoshi 的社交网络平台,这个平台曾经很流行,现在已经过气了。因为他对 Ruby 社区的贡献,于
在我的python应用程序中,我使用芹菜作为任务生产者和消费者,使用RabbitMQ作为代理。现在,我正在实施优先级排序。起初,它看起来根本不起作用,因为根据文档,我刚刚在队列中添加了参数。我更深入地研究了一下,发现了另一种优先级——消费者优先级和任务优先级。所以,现在,看起来有三种不同的优先顺序,我完全困惑了。你能给我解释一下区别吗? 队列最大优先级:即https://www.rabbitmq.
我们的情况如下: 我们有3个不同的Laravel项目,所有3个项目都依赖于我们的核心项目。该核心项目是一个单独的Laravel包,托管在我们的私人回购协议上,并用作其他项目的依赖项。 以前,每当Core项目发生变化时,我们只需在我们的服务器上为每个项目运行一个作曲家更新我们的供应商/ourcorepack来拉入核心更改。然而,由于最近作曲家似乎遭受严重的内存问题,当我们试图运行更新我们的数字海洋暂
Collaborators,协作者。一起协作开发,项目都会有一个主要的公共远程仓库。取决于你使用哪种协作开发的工作流程,一般你需要在项目的远程仓库设置一下,去添加项目的协作开发者。只有添加进来的开发者才有权限把他们自己对项目的提交推送到项目的公共远程仓库里。 添加协作者 在 Github 上,为项目添加协作者,先打开项目仓库页面,打开 Settings,在左边栏上在选择 Collaborators
附录B:作者/译者 英文作者 Alan A. A. Donovan is a member of Google’s Go team in New York. He holds computer science degrees from Cambridge and MIT and has been programming in industry since 1996. Since 2005, he