对于涉及使用阻塞和锁来调度进程的类项目,我们应该使用两个内核函数:
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。一旦条件为 true,wait_event_interruptible 返回 0。如果条件为 false,则将当前任务添加到 wait_queue_head_t状态为 TASK_INTERRUPTIBLE 的列表;当前进程将阻塞,直到调用wake_up_all(&q),然后它将重新检查CONDITION。如果当前任务在 CONDITION 变为 true 之前接收到信号,则宏返回 -ERESTARTSYS。
而wake_up_all的解释是:
通过将等待队列中的所有任务设置为 TASK_RUNNABLE 来唤醒它们。
我很难弄清楚这些功能到底是如何工作的以及如何一起使用它们。例如,什么时候检查 CONDITION? wait_event_interruptible 是持续轮询,还是仅在调用wake_up_all 时重新检查条件?这个解释有点不清楚。
如果您能给出如何一起使用这些功能的示例,那将非常有帮助。
wait_event_interruptible是持续轮询,还是只轮询 重新检查调用wake_up_all时的条件?这个解释是 有点不清楚。
调度程序的全部目的是避免在这种情况下进行轮询。您引用的内容精确地描述了发生的情况:仅在唤醒时重新检查条件,即例如给定任务正在等待生成数据:
消费者检查数据是否可用
如果不是(即条件为假),它就会进入睡眠状态 并被添加到等待队列
醒来后重试
在制作人方面
生成数据后,设置一些标志,或将某些内容添加到列表中 让消费者评价的条件成为真实
在等待队列上调用wake_up或wake_up