使用wait_event_interruptible

时间:2016-09-07 16:31:48

标签: linux-kernel linux-device-driver embedded-linux

我正在编写一个使用外部时钟执行定时功能的内核模块。基本上,模块对来自时钟的脉冲进行计数,每隔一段时间就会对计数进行滚动。用户进程可以使用ioctl要求以特定计数唤醒;然后他们执行一些任务并调用相同的ioctl等到下一次相同的计数出现。通过这种方式,他们可以使用这种外部定时定期执行。

我创建了一个wait_queue_head_t s数组,每个可用的调度时隙一个(即每个" count",如上所述)。当用户进程调用ioctl时,我只需使用指定调度时隙的ioctl参数调用sleep_on(),从而调用等待队列。当内核模块收到时钟脉冲并递增计数时,它会唤醒与该计数对应的等待队列。

我知道使用sleep_on()considered bad practice,因为状态可能会在测试之间发生变化以查看进程是否应该进入睡眠状态,以及相应的sleep_on()调用。但在这种情况下,我不会在睡觉前进行这样的测试,因为醒来事件是周期性的。如果我"只是错过"这并不重要。一个醒来的事件,因为另一个将很快到来(事实上,如果ioctl被调用非常接近指定的时间表槽,那么出现了问题,我宁愿等到下一个插槽)。

我已经考虑过使用wait_event_interruptible(),这被认为更安全,但我不知道要为wait_event_interruptible所需的条件参数添加什么。 wait_event_interruptible会在睡觉前检查这种情况,但我希望它在调用ioctl时始终处于睡眠状态。我可以使用我在睡觉之前清除并在唤醒之前设置的标志,但我担心这可能在等待队列中有多个进程的情况下不起作用 - 一个进程可能会完成并清除之前的标志接下来就被唤醒了。

我是否对此感到担忧?或者,wait_queue中的所有进程都保证在其中任何进程运行之前被唤醒(因此可以清除该标志)?有没有更好的方法来实现这样的系统?是否可以使用sleep_on()? (如果是,那么sleep_on()的版本是否可以中断?)

1 个答案:

答案 0 :(得分:2)

sleep_on的可中断版本为interruptible_sleep_on。请注意,自内核3.15以来,睡眠功能已被删除。

对于wait_event_interruptible,要求I want it to always sleep when the ioctl is invoked.并不常见。您可以使用标志,但此标志应为每个进程(或每个计划插槽)。或者您可以修改等待的计数至少为current_count + 1

在这种不常见的场景中,您可以使用它所包含的块,而不是宏wait_event_interruptible,并以您需要的方式排列它们。一般来说,任何等待都可以通过这种方式获得。