今天,在课堂上,我们学习了Linux中的等待队列,在讨论独占/非排他性等待时,出现了一些有趣的东西。
问了一个问题:,如果等待队列有一些进程在排他状态中等待,而另一些进程处于非排他状态时会发生什么。
讲师回答说,wake_up()
将遍历队列,唤醒所有非排他性进程,直到遇到排他进程,然后它就会唤醒最后一个进程并停止。
例如,:让N、E分别表示等待队列中的非排他性和排他性进程:
N - N - N - E - N - E - N - N
讲师声称前4个等待将被唤醒( The ),内核将在第一个E之后停止遍历。
这听起来很奇怪,因为E是排他性的,这意味着它不想和其他人一起被唤醒,而在本例中,是与其他人一起唤醒的。
在谷歌上搜索出以下问题:
当等待队列“唤醒”时,将为调度程序启用等待队列上的所有任务。如果使用独占函数将任务添加到等待队列中,则唤醒调用只会唤醒一个独占任务,而其他任务仍在等待。如果将排他任务和非排他任务混合添加到队列中,则唤醒函数将唤醒所有非排他任务,直到唤醒排他任务为止。唤醒顺序通常与将任务添加到队列的顺序相反。queues
哪一个是对的?真正的答案是完全不同的吗?
注意:在课堂上,我们讨论的是Linux2.4.18-14,i386 (如果系统需要更多信息,请评论)
发布于 2017-03-29 18:41:20
氮-氮
首先要注意的是,作为WQ_FLAG_EXCLUSIVE的条目被添加到队列的末尾,而不是在开始时。因此,引用的示例永远不会发生;等待队列总是排序的:所有Ns,然后所有Es。
因为E是排他性的,这意味着它不想和其他人一起被唤醒,在这种情况下,它是和其他人一起醒来的。
要注意的第二件事是,专属服务员不想被其他专属服务员吵醒。想当然地,非排外服务员正在执行完全不重叠的工作,而排他的侍者则从事相关的工作--也许他们都需要相同的共享资源,所以唤醒他们都会造成“雷鸣般的羊群”,因为他们都在尝试同一个锁。
因此,你通过谷歌发现的是正确的。大多数被告知的内容也是正确的,即Linux在唤醒了它找到的第一个独家服务员之后就停止了。然而,关于等待队列不按排他性排序的建议是不正确的。
https://stackoverflow.com/questions/39893500
复制相似问题