And*_*asa 5 linux linux-kernel thread-sleep
我有一个内核线程,它在具有FIFO和最高优先级的特定CPU上分配.该线程不时休眠,但时间间隔必须尽可能精确.那么考虑到这一点,在内核空间中最精确的睡眠方式是什么?
Sam*_*nko 17
以下是来自Documentation/timers/timers-howto.txt的相关摘录:
非原子背景:
您应该使用
*sleep[_range]函数系列.这里还有一些选项,虽然其中任何一个都可以正常工作,使用"正确"的睡眠功能将有助于调度程序,电源管理,并让你的驱动程序更好:)
- 由busy-wait循环支持:
udelay(unsigned long usecs)- 由hrtimers支持:
usleep_range(unsigned long min, unsigned long max)- 由jiffies/legacy_timers支持
msleep(unsigned long msecs)
msleep_interruptible(unsigned long msecs)与
*delay家庭不同,驱动这些呼叫的基本机制各不相同,因此您应该注意一些怪癖.睡觉"少数"USECS(<~10us?)
- 使用
udelay
- 为什么不
usleep呢?
在较慢的系统上,(嵌入式,或者可能是速度步进的PC!)设置hrtimers的开销usleep可能不值得.这样的评估显然取决于您的具体情况,但需要注意的是.睡觉~USECS或小型MSECS(10us - 20ms):
- 使用
usleep_range
- 为什么不
msleep(1ms - 20ms)?
最初在这里解释:
http://lkml.org/lkml/2007/8/3/250
msleep(1~20)可能无法执行调用者的意图,并且通常会睡得更久(实际睡眠时间约为20毫秒) 1~20ms范围).在许多情况下,这不是理想的行为.- 为什么没有
usleep/什么是好的范围?
由于usleep_range构建在hrtimers之上,唤醒将非常精确(ish),因此简单的usleep功能可能会引入大量不需要的中断.
通过引入范围,调度程序可以自由地将唤醒与其他可能因其他原因发生的唤醒合并,或者在最坏的情况下,为您的上限触发中断.
您提供的范围越大,您触发中断的可能性就越大; 这应该与特定代码路径的延迟/性能的可接受上限相平衡.这里的精确公差是特定于情况的,因此留给调用者来确定合理的范围.睡眠更大的MSECS(10ms +)
- 使用
msleep或可能msleep_interruptible
- 有什么不同?
msleep将当前的任务TASK_UNINTERRUPTIBLE,而msleep_interruptible把当前任务TASK_INTERRUPTIBLE调度睡觉前.简而言之,不同之处在于睡眠是否可以通过信号提前结束.一般情况下,只要使用,msleep除非您知道您需要可中断的变体.
我使用 hrtimer 和 waitqueue 的组合来使用内核线程实现周期性任务:
wait_event()/wait_event_timeout()wake_up()/wake_up_all()另外,刚刚发现,您可以使用hrtimer_init_sleeper()和实现睡眠schedule(),请参阅__wait_event_hrtimeout()或do_nanosleep()。但我没有尝试过。