咨询hrtimer不同初始化方式的区别及三种有效初始化行为差异
咱们先把这几种hrtimer的初始化逻辑和适用场景掰扯清楚,先澄清你提到的无效情况,再逐个拆解有效模式的差异:
先明确:第四种初始化确实无效
你已经注意到了,内核代码hrtimer.c里有这么一段判断:
if (clock_id == CLOCK_REALTIME && mode != HRTIMER_MODE_ABS) clock_id = CLOCK_MONOTONIC;
所以hrtimer_init(&timer, CLOCK_REALTIME, HRTIMER_MODE_REL)这种写法会被内核自动修正为CLOCK_MONOTONIC,和第二种初始化效果完全一致,不用单独考虑。
三种有效模式的详细解析
1. hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS)
你的理解完全正确:
- 用的是单调递增时钟:这个时钟从系统启动开始一直往上走,不受任何系统时间修改(比如管理员改时间、NTP同步跳变)的影响,永远不会回退。
- 定时器会在这个单调时钟的绝对时间点N到期:比如你设置的是系统启动后第3600秒,不管中间系统时间被改成什么,到了这个运行时长点就触发。
- 适用场景:需要和系统运行时长绑定的固定事件,比如“系统启动1小时后执行初始化检查”,或者需要和其他基于单调时钟的事件对齐的场景。
2. hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL)
这个也是你理解的那样:
- 同样基于单调时钟,定时器是从当前时刻开始,经过N时长后触发,这个时长是严格的物理时间,不会因为系统时间变化而变长或变短。
- 适用场景:这是内核里最常用的延时类场景,比如“10毫秒后处理某个硬件中断回调”“等待5秒后重试某个操作”,追求的是稳定、准确的延时长度。
3. hrtimer_init(&timer, CLOCK_REALTIME, HRTIMER_MODE_ABS)
这里需要纠正你一个小误解:系统时钟的变化是会影响到期时间的!
CLOCK_REALTIME就是系统的墙上时钟(真实世界的时间),如果管理员把系统时间从下午2点改成下午1点,原本设置在下午2:05到期的定时器会立刻触发(因为当前时间已经“超过”了到期点);如果把时间往后跳,定时器的触发时间也会跟着延后。- 这个模式的核心是绑定真实世界的绝对时间点,比如“2024年5月20日12:00:00”触发,不管系统运行了多久,只要墙上时钟到了这个点就执行。
- 适用场景:需要和真实日历时间同步的任务,比如每天凌晨执行备份、在某个特定日期触发固件更新,但要接受系统时间修改带来的触发时机变化。
选择建议
- 如果追求稳定、不受系统时间干扰的定时器:优先选前两种(
CLOCK_MONOTONIC的ABS或REL),做延时用REL,绑定系统运行时长点用ABS。 - 如果需要和真实世界时间绑定:只能选第三种(
CLOCK_REALTIME + ABS),但要提前考虑系统时间变化带来的异常触发情况。
内容的提问来源于stack exchange,提问作者uuwen
相关产品推荐
相关产品推荐

