如何为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
相关产品推荐
相关产品推荐

