我是一个内核新手。 阅读源代码时,我刚刚得到了这个问题。
在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()
之前调用唤醒函数[以及正常执行期间]。