Linux等待队列-排他和非排他的组合

Dea*_*orf 2 c linux multithreading wait wakeup

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

提出了一个问题: 如果等待队列中有一些进程处于排他状态,而另一些处于非排他状态,将会发生什么情况。

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

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

N - N - N - E - N - E - N - N 
Run Code Online (Sandbox Code Playgroud)

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

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

搜索该问题得出以下结果:

当“唤醒”等待队列时,将为调度程序启用等待队列上的所有任务。如果使用排他功能将任务添加到等待队列中,则唤醒调用将仅唤醒一个排他任务,而其他任务仍在等待。如果将排他任务和非排他任务的混合添加到队列中,则唤醒功能将唤醒所有非排他任务,直到它唤醒排他任务。唤醒顺序通常与将任务添加到队列的顺序相反。 https://blackfin.uclinux.org/doku.php?id=linux-kernel:wait_queues

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

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

小智 5

N - N - N - E - N - E - N - N
Run Code Online (Sandbox Code Playgroud)

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

由于E是排他性的,因此它不希望与其他任何人一起被唤醒,在这种情况下,它与其他人一起被唤醒

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

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