7

当从时间服务器更新系统时间或由于 DST 更改时,有没有办法得到通知?我在 API/系统调用或等效项之后。

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

4

3 回答 3

7

您可以使用timerfd_create(2)创建一个计时器,然后TFD_TIMER_CANCEL_ON_SET在设置时用选项标记它。将其设置为将来不合理的时间,然后对其进行阻止(使用轮询/选择等)-如果系统时间更改,则计时器将被取消,您可以检测到。

(这就是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;
}
于 2019-10-25T15:45:29.643 回答
4

我不知道是否有办法通知系统时间的变化,但是

  • 系统时间存储为 UTC,因此不会因 DST 更改而更改通知。

  • 如果我没记错的话,NTP 守护进程通常会通过改变其速度来调整时钟,同样不会通知任何更改。

因此,您会收到通知的唯一时间是在不常见的操作之后。

于 2010-02-12T12:18:00.687 回答
1

clock_gettime在最近的 Linux 系统上速度非常快,而且通常也非常精确;您可以使用clock_getres. 但是对于小时级别的时间戳,gettimeofday可能会更方便,因为它可以为您进行时区调整。

每次需要时间戳时,只需调用适当的系统调用并划分为小时;来自 NTP 的所有其他时间调整或已经为您完成的任何操作。

于 2010-02-12T12:17:40.437 回答