今天在课堂上我们研究了Linux中的等待队列,在讨论独占/非独占等待时出现了一些有趣的事情。
提出了一个问题: 如果等待队列有一些进程在独占状态等待而其他进程处于非独占状态,会发生什么。
讲师回答说wake_up()
将遍历队列,唤醒所有非独占进程,直到它遇到一个独占进程,然后它将唤醒最后一个进程并停止。
例如: 设N,E分别代表等待队列中的非排他和独占进程:
N - N - N - E - N - E - N - N
讲师声称前4个等待将被唤醒(N-N-N-E),并且内核将在第一个E之后停止遍历。
这听起来很奇怪,因为E是独家的,这意味着它不想与其他人一起被唤醒,在这种情况下 与其他人一起醒来。
谷歌搜索问题产生了以下结果:
当等待队列被“唤醒”时,等待队列上的所有任务都是 已启用调度程序。如果使用a将任务添加到等待队列 独占功能然后唤醒呼叫只会唤醒一个 独家任务让其他人仍在等待。 如果是混合物 然后将独占任务和非独占任务添加到队列中 唤醒功能将唤醒任何非独占任务,直到它 唤醒专属任务。唤醒命令通常是相反的 任务添加到队列的顺序。 https://blackfin.uclinux.org/doku.php?id=linux-kernel:wait_queues
哪一个是正确的?真正的答案是完全不同的吗?
注意:在课堂上我们讨论的是Linux2.4.18-14,i386(如果系统需要其他信息,请发表评论)
答案 0 :(得分:5)
N - N - N - E - N - E - N - N
首先要注意的是,WQ_FLAG_EXCLUSIVE条目被添加到队列的末尾而不是开头。因此,引用的例子永远不会发生;等待队列总是排序:所有Ns,然后全部Es。
因为E是独家的,这意味着它不想被其他人吵醒,在这种情况下,它会被其他人唤醒
第二件需要注意的是,独家服务员不希望与其他独家服务员一起醒来。推定,非独家服务员表现完全不重叠的工作,而独家服务员则是做相关的工作 - 也许他们都需要相同的共享资源,所以唤醒他们所有会导致“雷鸣般的群体”,因为他们都尝试相同的锁。
因此,您通过Google找到的内容是正确的。你被告知的大多数是也正确,即Linux唤醒它找到的第一个独家服务员后停止。但是,关于等待队列未被排他性排序的建议是不正确的。