Linux内核中wait_event和wake_up之间的争用条件

我是一个内核新手。 阅读源代码时,我刚刚得到了这个问题。

wait_event()的实现中,内核就是这样做的:

 ... prepare_to_wait(); /* enqueue current thread to the wait queue */ ... schedule(); /* invoke deactivate_task() inside, which will dequeue current thread from the runqueue */ ... 

在执行“wake_up()”时,内核执行如下操作:

 ... try_to_wake_up(); /* invoke activate_task() inside, which will enqueue the target thread into the runqueue */ ... 

并发执行中,如果按以下顺序调用上述函数呢?

 ... prepare_to_wait(); /* thread A adds itself to the wait queue */ ... try_to_wake_up(); /* thread B wakes up A and enqueues it into the runqueue */ ... schedule(); /* thread A dequeues itself from the runqueue and yields the CPU */ ... 

线程A不在runqueue或等待队列中。 这是否意味着我们失去了线程? 内核必须有一些机制来防止这种情况的发生。 有人能告诉我我在这里错过了什么吗? 谢谢!

我在Kedar Sovani于 2005年7月28日发表的Linux Journal第137期文章coreel Korner – Sleeping in the coreel中找到了答案。

简而言之,这是失败的唤醒问题。 Linux内核通过将任务状态设置为TASK_INTERRUPTIBLE来解决这个问题。 这导致调用schedule()立即唤醒,即使有人在调用schedule()之前调用唤醒函数[以及正常执行期间]。