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

ric*_*hau 2 linux-device-driver linux-kernel 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功能.

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

CL.*_*CL. 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);
}
Run Code Online (Sandbox Code Playgroud)

如果此实现(或许多其他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);
}
Run Code Online (Sandbox Code Playgroud)