如何在Linux中检测系统时间的更改?

9

有没有一种方法可以在时间服务器更新或由于DST更改时收到通知?我需要一个API /系统调用或等效物。

这是我努力优化生成类似于SQL NOW()的值到小时粒度而不使用SQL的一部分。


你为什么不在需要时直接使用系统调用获取本地时间? - Romain
@Romain:对于我的应用程序来说太贵了。 - ϹοδεMεδιϲ
请参见 https://dev59.com/1GPVa4cB1Zd3GeqP7JUS - user
3个回答

12
您可以使用 timerfd_create(2) 创建一个定时器,然后在设置定时器时使用 TFD_TIMER_CANCEL_ON_SET 选项标记它。将它设置为未来的一个不合理的时间,然后阻塞它(使用 poll/select 等)- 如果系统时间发生变化,则该定时器将被取消,您可以检测到这种情况。(这就是 systemd的实现方式) 例如:
#include <sys/timerfd.h>
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>

int main(void) {
        int fd = timerfd_create(CLOCK_REALTIME, 0);
        timerfd_settime(fd, TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET,
                        &(struct itimerspec){ .it_value = { .tv_sec = INT_MAX } },
                        NULL);
        printf("Waiting\n");
        char buffer[10];
        if (-1 == read(fd, &buffer, 10)) {
                if (errno == ECANCELED)
                        printf("Timer cancelled - system clock changed\n");
                else
                        perror("error");
        }
        close(fd);
        return 0;
}

1
这个代码在夏令时改变时会触发吗? - Howard Hinnant
1
@HowardHinnant 像 AProgrammer 在他的回答中所说的那样,夏令时的更改(至少在我的情况下)变得不太重要。据我了解,如果您仅使用时区信息进行展示,并在 UTC 中执行所有操作,则 DST 更改应该无关紧要。 - ϹοδεMεδιϲ

4

我不知道是否有一种方法可以通知系统时间的更改,但是

  • 系统时间以UTC格式存储,因此由于DST更改而导致的更改不会被通知。

  • 如果我没记错的话,NTP守护进程通常通过改变速度来调整时钟,因此也不需要通知。

因此,您只有在进行不常见的操作后才会收到通知。


1

在大多数最新的Linux系统上,clock_gettime非常快,并且通常也非常精确;您可以使用clock_getres来查找精度。但是对于小时级别的时间戳,gettimeofday可能更方便,因为它可以为您执行时区调整。

只需调用适当的系统调用并在每次需要时间戳时进行小时分割即可;所有其他来自NTP或其他任何地方的时间调整都已经为您完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接