4

我是内核新手。我在阅读源代码时遇到了这个问题。

在 的实现中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 不在运行队列或等待队列中。这是否意味着我们丢失了线程 A?内核必须有某种机制来防止这种情况发生。有人可以告诉我我在这里错过了什么吗?谢谢!

4

2 回答 2

4

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

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

于 2013-09-23T15:32:41.017 回答
0

来自内核的机制之一是 wait_event*() 宏。它以Kernel Korner - Sleeping in the Kernel中解释的方式工作

于 2019-07-20T07:43:28.097 回答