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

如何为Linux帧缓冲数字时钟创建可重复调用天气API的定时器?

解决方法

一、在时钟程序内部实现定时器(推荐)

直接在现有程序中整合定时逻辑,和主进程共用一个上下文,从根源避免文件读写冲突。可以用Linux的timerfd系列接口,比sleep更精准,还能适配后续的事件循环扩展。

结合你现有的时钟代码,示例如下:

#include <sys/timerfd.h>
#include <unistd.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

void fetch_weather() {
    // 这里编写调用天气API的逻辑
    printf("正在获取天气数据...\n");
}

int main() {
    int timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
    if (timer_fd == -1) {
        perror("timerfd_create 失败");
        exit(1);
    }

    // 设置定时周期:30分钟(30*60秒),如果要1小时就改成3600
    struct itimerspec ts;
    ts.it_interval.tv_sec = 30 * 60;
    ts.it_interval.tv_nsec = 0;
    // 首次触发延迟1秒,避免程序启动立刻调用API
    ts.it_value.tv_sec = 1;
    ts.it_value.tv_nsec = 0;

    if (timerfd_settime(timer_fd, 0, &ts, NULL) == -1) {
        perror("timerfd_settime 失败");
        close(timer_fd);
        exit(1);
    }

    // 主循环:同时处理时钟更新和定时器事件
    char buf[20], tbuf[10];
    while (1) {
        // 更新时钟显示内容
        time_t rawtime;
        struct tm *timeinfo;
        time(&rawtime);
        timeinfo = localtime(&rawtime);
        strftime(buf, sizeof(buf), "%d-%b-%Y", timeinfo);
        strftime(tbuf, sizeof(tbuf), "%H:%M", timeinfo);
        printf("当前时间:%s %s\n", buf, tbuf);

        // 检查定时器是否触发
        uint64_t expirations;
        ssize_t ret = read(timer_fd, &expirations, sizeof(expirations));
        if (ret == sizeof(expirations)) {
            fetch_weather();
        }

        // 每秒更新一次时钟,避免占用过多系统资源
        sleep(1);
    }

    close(timer_fd);
    return 0;
}

二、保留cron任务,解决文件冲突问题

如果坚持用cron,通过文件锁确保同一时间只有一个进程读写共享文件,彻底避免冲突。

1. 主程序中添加文件锁逻辑

在读写共享文件的代码前后加锁:

#include <sys/file.h>
#include <stdio.h>

void write_shared_data(const char *data) {
    FILE *fp = fopen("/path/to/shared/file", "w");
    if (!fp) {
        perror("fopen 失败");
        return;
    }

    // 加排他锁
    if (flock(fileno(fp), LOCK_EX) == -1) {
        perror("flock 失败");
        fclose(fp);
        return;
    }

    fputs(data, fp);

    // 解锁
    flock(fileno(fp), LOCK_UN);
    fclose(fp);
}

2. cron脚本中添加锁逻辑

对应的cron执行脚本(比如fetch_weather.sh)也要加锁:

#!/bin/bash

LOCK_FILE="/tmp/weather_lock"
# 用flock获取排他锁,超时10秒则退出
flock -x -w 10 "$LOCK_FILE" || exit 1

# 调用天气API并写入共享文件
curl -s "你的天气API地址" > /path/to/shared/file

# 脚本结束后自动释放锁

然后在crontab中配置定时任务:

# 每30分钟执行一次,要1小时就改成0 */1 * * *
*/30 * * * * /path/to/fetch_weather.sh

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:25:11