进程会在抢占式内核中失去唤醒机会吗?

Will process lost wake-up chance in a preemptive kernel?

通常,当进程想要等待一些不可用的事件时,我们可以让它们进入休眠状态,等事件发生后再唤醒它们。

下面熟悉的代码完成了这个任务:

while (!events) {
    DEFINE_WAIT(wait);

    prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE);
    if (!events)
        schedule();
    finish_wait(&q, &wait);
}

假设在一个抢占式内核中存在两个进程,进程A是生产者,进程B是消费者。进程B正在执行上面的代码,等待进程A产生的一些数据生效。

现在,我认为如果两个进程的执行路径如下所示,进程B将失去唤醒机会。

  1. 进程 B 检查 while 语句中的事件,现在它是 return false。
  2. 进程 B 执行 DEFIN_WAIT(wait).
  3. 进程 A 在进程 B 执行完 DEFIN_WAIT(wait) 之后和执行 prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE); 之前产生一些数据。
  4. 进程 B 执行 prepare_to_wait(&q, &wait, TASK_INTERRUPTIBLE);.
  5. 进程 B 在执行之前被其他进程抢占 if (!events)

因为进程B现在的状态是TASK_INTERRUPTIBLE,所以不会再调度到CPU。所以,我认为,进程B永远不会被唤醒....

您的最终判断是错误的:抢占不适用于任务状态。所以,即使在TASK_INTERRUPTIBLE状态下被抢占的任务也可以再次获得CPU。

参见,例如 this or that