我有一个内核线程,它在具有FIFO和最高优先级的特定CPU上分配。该线程不时休眠,但时间间隔必须尽可能精确。那么考虑到这一点,在内核空间中最精确的睡眠方式是什么?
答案 0 :(得分:13)
以下是Documentation/timers/timers-howto.txt的相关摘录:
非原子上下文:
您应该使用
*sleep[_range]
系列函数。 这里还有一些选择,而其中任何一个都可以 正确地工作,使用"权利"睡眠功能会 帮助调度程序,电源管理,并让你的 司机更好:)
- 由忙等待循环支持:
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或小型MSEC(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
你知道你需要可中断的变种。
答案 1 :(得分:0)
我使用了hrtimer和waitqueue的组合来使用内核线程实现定期任务:
wait_event()/wait_event_timeout()
wake_up()/wake_up_all()
另外,刚刚找到,您可以使用hrtimer_init_sleeper()
和schedule()
实现睡眠,请参阅__wait_event_hrtimeout()或do_nanosleep()。但是我在那里试过了。