2

我在 Linux 上有一个应用程序,它需要每小时更改一些参数,例如在 11:00、12:00 等,并且用户可以随时更改系统的日期。

当一小时从 xx:59 变为 xx+1:00 时,是否有任何信号、posix 函数可以提供给我?

通常,我使用localtime(3)每秒获取当前时间,然后比较分钟部分是否等于0. 但是,它看起来不是一个好方法,为了检测变化,我需要每秒调用相同的函数一个小时。特别是我在嵌入式板上运行代码,这样可以减少资源的使用。

这是一个示例代码,我是如何做到的:

static char *fetch_time() { // I use this fcn for some other purpose to fetch the time info
    char *p;
    time_t rawtime;
    struct tm * timeinfo;
    char buffer[13];
    time(&rawtime);
    timeinfo = localtime(&rawtime);

    strftime (buffer,13,"%04Y%02m%02d%02k%02M",timeinfo);
    p = (char *)malloc(sizeof(buffer));
    strcpy(p, buffer);
    return p;
}


static int hour_change_check(){
    char *p;
    p = fetch_time();
    char current_minute[3] = {'\0'};
    current_minute[0] = p[10];
    current_minute[1] = p[11];
    int current_minute_as_int = atoi(current_minute);
    if (current_minute_as_int == 0){
        printf("current_min: %d\n",current_minute_as_int);
        free(p);
        return 1;
    }
    free(p);
    return 0;
}

int main(void){
    while(1){
    int x = hour_change_check();
    printf("x:%d\n",x);
    sleep(1);
    }
    return 0;
}
4

2 回答 2

2

没有这样的信号,但传统上等到某个目标时间的方法是计算“现在”和“那么”之间的时间,然后调用sleep()

now = time(NULL);
when = (some calculation);
if (when > now)
    sleep(when - now);

如果您需要非常精确地了解从例如 3:59:59 到 4:00:00 的转换,您可能希望睡眠时间稍短一些,以防闰秒导致时间调整。(如果您在时区可以更改的便携式设备中运行,您还需要担心选择新位置,如果它在半小时偏移上运行,则重做所有计算。沙特阿拉伯甚至还有太阳时....)

编辑:根据 R.. 的建议,如果clock_nanosleep()可用,计算timespec绝对唤醒时间的值并用TIMER_ABSTIME标志调用它。有关. _ _ clock_nanosleep()但是,如果允许时间倒退(例如,带区域偏移的本地时间),您可能仍需要进行一些维护检查。

于 2013-08-10T21:42:43.500 回答
0

您是否实际测量过每秒轮询一次时间的解决方案中使用的开销(或者甚至两次,给出您的一些其他评论)?

调用的指令数量最少,并且您没有任何循环。所以更糟糕的是,cpu 可能使用 100 微秒(0.1 毫秒或 0.0001 秒)的时间。这个估计很大程度上取决于嵌入式系统中使用的处理器及其时钟速度,但想法是轮询逻辑可能使用总可用时间的 1/1000。

此外,您可以优化您的hour_change_check代码以执行所有时间计算,而不是调用另一个malloc必须立即释放的函数!此外,如果这是一个嵌入式 *nix 系统,您是否仍然可以在其自己的线程中运行此轮询逻辑,以便在它发出sleep()时不会干扰或延迟其他工作单元。

因此,测量问题并查看它是否是一个重大问题。轮询的性能必须与当用户更改时间时必须检测到小时更改的要求相平衡。也就是说,我认为即使用户更改时间,每秒轮询也会捕获小时翻转,但开销值得。那么,到底有多少开销?

于 2013-08-11T07:25:27.323 回答