何时使用linux内核add_timer vs queue_delayed_work

时间:2013-01-11 09:29:14

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

要安排稍后在Linux内核驱动程序中执行的操作,我有两个选项:

  • add_timer
  • queue_delayed_work

我知道的一个区别是:对于定时器,您需要指定expires,这是定时器到期时的jiffies值,对于延迟工作,您需要指定jiffies的延迟。

我一直在阅读关于计时器和work_queue的其他questions,并且它提到计时器在进程外环之外运行。这与延迟工作不同吗?

我也知道定时器存在问题,在计算expires时,可能会发生值溢出,因此计算出的值小于当前的jiffies并且计时器立即过期(如果我',请更正我我错了)。延迟工作是否会遭受同样的问题?如果是的话,怎么做

对我而言,使用延迟工作似乎更容易(因为工作不是定期的)。但是使用计时器有什么不利之处?

修改 我做了一些进一步的研究。似乎queue_delayed_work仅在内部使用add_timer

所以我的新问题是,如何正确处理定时器的jiffies溢出?例如,如何将timer / delayed_work设置为10分钟延迟?

3 个答案:

答案 0 :(得分:2)

正如我在问题中所述,queue_delayed_work仅在内部使用add_timer。所以使用是一样的。

答案 1 :(得分:2)

回答你的第二个问题。

从现在开始10分钟,用于内核计时器:

// 10 minutes * 60 converts to seconds * 1000 converts to microseconds
// msecs_to_jiffies converts the resulting microsecond delay to jiffies
//   which is added to the current time (system variable jiffies)

jiffies + msecs_to_jiffies(10 * 60 *1000)

对于排队延迟工作,您只需使用10分钟延迟部分:

msecs_to_jiffies(10 * 60 * 1000)

重新溢出 - 如果你需要自己比较jiffies,请参阅time_after和time_before(和其他)宏 http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/include/linux/jiffies.h#L93

答案 2 :(得分:2)

在内核编程的情况下,当你的定时器/工作的回调函数需要睡眠时,你必须使用delayed_work。由于delayed_work在进程上下文中运行,您可以使用那些可能在回调函数内睡眠或倾向于睡眠的函数。在内核计时器的情况下,您不能使用那些睡眠或倾向于睡眠的功能。 结论:如果您的回调函数需要休眠,则使用工作队列,否则使用计时器/ tasklet。

希望有所帮助:)