对于涉及使用阻塞和锁定的调度进程的类项目,我们应该使用两个内核函数:
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来唤醒等待队列中的所有任务。
我很难弄清楚这些功能的确切运作方式以及如何将它们结合使用。例如,什么时候检查CONDITION? wait_event_interruptible是否连续轮询,还是仅在调用wake_up_all时重新检查条件?这个解释有点不清楚。
如果您可以举例说明如何将这些功能结合使用,那将非常有用。
答案 0 :(得分:1)
wait_event_interruptible是否继续轮询,或仅执行此操作 调用wake_up_all时重新检查条件?这个解释是 有点不清楚。
调度程序的重点是避免在这种情况下进行轮询。所引用的内容在您引用的内容中有详细描述:条件仅在wake_up上重新检查,即例如,如果给定任务正在等待生成数据:
消费者检查数据是否可用
如果没有(即条件为假),它会进入睡眠状态 并被添加到等待队列
在醒来时重试
在生产者方面
生成数据后,设置一些标志,或向列表中添加内容 以便消费者评估的条件成为真实
在waitqueue上调用wake_up或wake_up
现在,我建议您尝试使用它们,如果它不能按照您想要的方式运行,请回复您尝试过的其他问题和代码。