今天,在类里面,我们研究了Linux中的等待队列,并在谈论独占/非独占等待时出现了一些有趣的事情。

提出了一个问题:
如果等待队列中有一些进程在排他状态下等待而其他进程在非排他状态下会发生什么。

讲师回答说,wake_up()将遍历队列,唤醒所有非独占进程,直到遇到独占进程,然后它将唤醒最后一个进程并停止。

例如:
令N,E分别代表等待队列中的非排他性和排他性过程:

N - N - N - E - N - E - N - N

讲师声称前四个等待将被唤醒(N-N-N-E),内核将在第一个E之后停止遍历。

这听起来很奇怪,因为E是排他性的,这意味着它不想与其他任何人一起被唤醒,在这种情况下,是与他人一起被唤醒的

对该问题进行谷歌搜索得出以下结果:



哪一个是正确的?真正的答案是完全不同的吗?

注意:在类里面我们谈论的是Linux2.4.18-14,i386(如果系统上需要其他信息,请发表评论)

最佳答案



首先要注意的是,将WQ_FLAG_EXCLUSIVE的条目添加到队列的末尾而不是开头。因此,所引用的示例永远不会发生。等待队列始终排序:所有N,然后所有E。



要注意的第二件事是,排他性服务员不想与其他排他性服务员一起醒来。据推测,非排他性服务员正在执行完全不重叠的工作,而排他性服务员正在做相关的工作-也许他们都需要相同的共享资源,因此唤醒它们都将导致“雷鸣群”,因为他们都尝试相同的资源锁。

因此,您通过Google找到的信息是正确的。告诉您的大多数信息也是正确的,即Linux在唤醒它找到的第一个独占服务员后停止。但是,关于等待队列未按排他性排序的建议是不正确的。

10-06 14:58