C语言 同时使用可中断的等待事件和全部唤醒

vxqlmq5t  于 2023-01-01  发布在  其他
关注(0)|答案(1)|浏览(166)

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

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

wait_event_interruptible的解释如下:
阻塞等待队列中的当前任务,直到CONDITION变为真。
这实际上是一个宏,它反复计算CONDITION,CONDITION是一段C代码,比如foo == bar或者function()〉3,一旦条件为真,wait_event_interruptible返回0,如果条件为假,当前任务以TASK_INTERRUPTIBLE状态加入wait_queue_head_t列表;当前进程将阻塞,直到wake_up_all(&q)被调用,然后它将重新检查CONDITION。2如果当前任务在CONDITION变为真之前接收到信号,宏将返回-ERESTARTSYS。
对wake_up_all的解释是:
通过将等待队列中的所有任务的状态设置为TASK_RUNNABLE来唤醒这些任务。
我很难弄清楚这些函数到底是如何工作的,以及如何一起使用它们。例如,什么时候检查CONDITION?wait_event_interruptible是连续轮询,还是只在wake_up_all被调用时才重新检查条件?这个解释有点不清楚。
如果你能给予一个如何一起使用这些函数的例子,那将会非常有帮助。

xzv2uavs

xzv2uavs1#

wait_event_interruptible是连续轮询,还是只在wake_up_all被调用时重新检查条件?这个解释有点不清楚。
调度器的全部意义在于避免在这种情况下进行轮询。所发生的事情在你引用的内容中有精确的描述:仅在wake_up时重新检查条件,即,例如,如果给定任务正在等待产生数据:

  • 消费者检查数据是否可用
  • 如果不是(即条件为假),则它进入休眠并被添加到等待队列
  • 唤醒时重试

而在生产者方面

  • 生成数据后,设置某个标志或向列表中添加某些内容,以便使用者计算的条件变为真
  • 调用waitqueue上的wake_up或wake_up all

相关问题