一起使用wait_event_interruptible和wake_up_all

对于涉及使用阻塞和锁定调度进程的类项目,我们应该使用两个内核函数:

int wait_event_interruptible(wait_queue_head_t q, CONDITION); void wake_up_all(wait_queue_head_t *q); 

wait_event_interruptible的解释是:

阻止等待队列上的当前任务,直到CONDITION变为true。

这实际上是一个宏。 它重复计算CONDITION,它是C代码的一个片段,如foo == bar或function()> 3.一旦条件为真,wait_event_interruptible返回0.如果条件为false,则将当前任务添加到wait_queue_head_t列表与状态TASK_INTERRUPTIBLE; 当前进程将阻塞,直到调用wake_up_all(&q),然后它将重新检查CONDITION。 如果当前任务在CONDITION变为true之前收到信号,则宏返回-ERESTARTSYS。

而wake_up_all的解释是:

通过将状态设置为TASK_RUNNABLE来唤醒等待队列中的所有任务。

我很难弄清楚这些function究竟是如何工作的,以及如何将它们结合使用。 例如,何时检查CONDITION? wait_event_interruptible是否连续轮询,还是仅在调用wake_up_all时重新检查条件? 这个解释有点不清楚。

如果您可以举例说明如何将这些function结合使用,那将非常有用。

wait_event_interruptible是否连续轮询,还是仅在调用wake_up_all时重新检查条件? 这个解释有点不清楚。

调度程序的重点是避免在这种情况下进行轮询。 所引发的内容在您引用的内容中有详细描述:条件仅在wake_up上重新检查,即,例如,如果给定任务正在等待生成数据:

  • 消费者检查数据是否可用

  • 如果不是(即条件为false),它将进入hibernate状态并被添加到等待队列中

  • 醒来时重试

而在生产者方面

  • 生成数据后,设置一些标志,或者向列表中添加一些内容,以便消费者评估的条件变为真

  • 在waitqueue上调用wake_up或wake_up

现在,我建议你尝试使用它们,如果它不能按照你想要的方式工作,那么回过头来试试另一个问题和代码。