gpt4 book ai didi

Linux 内核 : how to wait in multiple wait queues?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:09:25 26 4
gpt4 key购买 nike

我知道如何使用 wait_event 在 Linux 内核队列中等待以及如何唤醒它们。

现在我需要弄清楚如何同时在多个队列中等待。我需要多路复用多个事件源,基本上以类似于 pollselect 的方式,但由于事件源没有可轮询文件描述符的形式,我无法在这些系统调用的实现中找到灵感。

我最初的想法是从 wait_event 宏中获取代码,多次使用 DEFINE_WAIT 以及 prepare_to_wait

但是,考虑到 prepare_to_wait 的实现方式,如果多次添加相同的“等待者”,恐怕队列的内部链表会损坏(如果一个队列可能会发生这种情况导致唤醒,但不满足等待条件并重新开始等待)。

最佳答案

在多个等待队列中等待的可能场景之一:

int ret = 0; // Result of waiting; in form 0/-err.

// Define wait objects, one object per waitqueue.
DEFINE_WAIT_FUNC(wait1, default_wake_function);
DEFINE_WAIT_FUNC(wait2, default_wake_function);

// Add ourselves to all waitqueues.
add_wait_queue(wq1, &wait1);
add_wait_queue(wq2, &wait2);

// Waiting cycle
while(1) {
// Change task state for waiting.
// NOTE: this should come **before** condition checking for avoid races.
set_current_state(TASK_INTERRUPTIBLE);
// Check condition(s) which we are waiting
if(cond) break;
// Need to wait
schedule();
// Check if waiting has been interrupted by signal
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
}
// Remove ourselves from all waitqueues.
remove_wait_queue(wq1, &wait1);
remove_wait_queue(wq2, &wait2);
// Restore task state
__set_current_state(TASK_RUNNING);
// 'ret' contains result of waiting.

请注意,此场景与wait_event之一略有不同:

wait_event 使用 autoremove_wake_function 等待对象(使用 DEFINE_WAIT 创建)。此函数从 wake_up() 调用,从队列中删除等待对象。因此需要重新添加等待对象到队列每次迭代

但是在多个等待队列的情况下,不可能知道哪个等待队列被触发了。因此,遵循此策略需要在每次迭代时重新添加 每个等待对象,这是低效的。

相反,我们的场景使用 default_wake_function 作为等待对象,因此该对象不会在 wake_up() 调用时从等待队列中移除,添加等待对象就足够了在循环之前只进入队列一次。

关于Linux 内核 : how to wait in multiple wait queues?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40018689/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com