简单休眠(使用wait_event _ *()函数)和高级休眠(使用prepare_to_wait()函数)有什么区别?

时间:2014-09-21 04:13:52

标签: linux-kernel linux-device-driver embedded-linux

在LDD3一书中,它介绍了简单的休眠(wait_event *()函数)和提前休眠(prepare_to_wait()函数)。

如果我的理解是正确的,那么wait_queue_t似乎是一个进程条目,但wait_queue_head_t似乎是等待队列来存储正在添加(wait_queue_t)的进程列表..

因此,令我感到困惑的是,我应该使用wait_event _ *()函数与prepare_to_wait使用指定等待进程的情况。

我能告诉的唯一原因是我可以在睡觉前指定过程状态与简单睡眠。但是,简单的睡眠确实提供了可中断和不间断的wait_event功能..

所以,我有点困惑为什么从设计和实现的角度来看我们都需要两个。感谢。

1 个答案:

答案 0 :(得分:5)

这是wait_event()很多简化)的实现:

#define wait_event(wq, condition)
{
    DEFINE_WAIT(wait);
    for (;;) {
        prepare_to_wait(&wq, &wait, TASK_UNINTERRUPTIBLE);
        if (condition)
            break;
        schedule();
    }
    finish_wait(&wq, &wait);
}

如果此实现(或许多其他wait_event_*变体之一)适合您,那么您应该只使用它。

但是,可能存在需要对此等待循环进行更多控制的情况。 例如,假设您要等待某些数据在缓冲区中可用并返回,并且这两个操作都需要在锁定下完成,并且检查数据删除数据需要是一个原子操作,即两者必须在同一个锁下完成,中间没有解锁。 然后你必须像这样修改上面的循环:

void my_own_wait(...)
{
    DEFINE_WAIT(wait);
    spin_lock(&lock);
    while (!some_data_available()) {
        prepare_to_wait(&wq, &wait, TASK_xxx);
        spin_unlock(&lock);
        schedule();
        spin_lock(&lock);
        finish_wait(&wq, &wait);
    }
    take_data();
    spin_unlock(&lock);
}