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

时间:2013-09-23 06:32:09

标签: linux concurrency linux-kernel race-condition

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

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

2 个答案:

答案 0 :(得分:3)

我在2005年7月28日由 Kedar Sovani 撰写的Kernel Korner - Sleeping in the Kernel in Issue 137 of the Linux Journal文章中找到了答案。

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

答案 1 :(得分:0)

内核的一种机制是wait_event *()宏。它以Kernel Korner - Sleeping in the Kernel

中所述的方式工作