You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:60Hz定时器在Windows正常但Linux下失效问题(附代码)

嘿,我帮你排查出问题所在了,咱们一步步拆解:

问题出在哪?

你现在用的clock()函数根本不是用来测真实时间的!它统计的是你的进程实际占用的CPU时间,不是墙上流逝的真实时间:

  • Windows下你的程序是死循环忙等,CPU几乎被占满,所以CPU时间和真实时间几乎同步,定时器看起来能按60Hz跑。
  • 但Linux下系统调度器会把CPU分给其他进程,或者你的程序没拿到实时调度权限,导致CPU时间的增长比真实时间慢。比如真实时间过了32ms,你的进程才攒够16ms的CPU时间,这时候定时器才触发,实际间隔就变成了32ms,60次下来就是差不多2秒,正好和你看到的输出对上。

另外你的定时器逻辑还有个小bug:触发时你用pre += diff更新时间,而不是pre += 16*PRE_MS。这会让每次的延迟都累积下来,哪怕CPU时间和真实时间同步,长期下来定时器也会越来越不准。

怎么改?

要做跨平台的高精度定时器,得用专门测真实时间的函数,别再用clock()了。给你写了个兼容Windows和Linux的版本:

#include <stdio.h>
#include <time.h>

// 跨平台获取当前毫秒级真实时间
long long get_current_ms() {
#ifdef _WIN32
    // Windows用GetTickCount64,需要链接kernel32库
    return (long long)GetTickCount64();
#else
    // Linux用单调时钟,不受系统时间调整影响
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (long long)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
#endif
}

int main() {
    long long pre = get_current_ms();
    int cnt = 0;
    // 60Hz对应约16.6ms,这里用16ms或者调整成17ms都可以,看你需求
    const long long interval_ms = 16;

    while (1) {
        long long now = get_current_ms();
        long long diff = now - pre;
        if (diff >= interval_ms) {
            cnt++;
            if (cnt >= 60) {
                printf("%lld\n", pre);
                cnt = 0;
            }
            // 重点:更新为下一次预期触发时间,避免延迟累积
            pre += interval_ms;
            // 如果系统卡顿太久,直接跳到当前时间,避免一次性触发N次
            if (pre < now) {
                pre = now;
            }
        }
    }
}

编译注意事项

  • Windows(MinGW GCC):编译时要链接kernel32库,命令:gcc timer.c -o timer.exe -lkernel32
  • Linux:有些版本需要链接rt库,命令:gcc timer.c -o timer -lrt(新版GCC可能不用,但加上更稳妥)
额外小贴士
  1. 用CLOCK_MONOTONIC而不是系统时间,因为系统时间可能被手动修改或者NTP同步跳变,单调时钟只会一直递增,适合做定时器。
  2. 如果要严格卡60Hz,可以把间隔改成16667微秒(也就是16.667ms),用微秒级计算会更精准。
  3. 死循环会占100%CPU,要是想降低占用,可以在循环里加个短暂休眠,比如Linux下usleep(1000),Windows下Sleep(1),这样CPU占用会降下来,精度也够60Hz用。

内容的提问来源于stack exchange,提问作者叶ch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:40:24