温馨提示×

ubuntu定时器如何设置超时时间

小樊
48
2025-11-02 08:51:51
栏目: 智能运维

Ubuntu系统中设置定时器超时时间的常见方法

1. 使用systemd定时器(推荐,适用于大多数场景)

systemd是Ubuntu的初始化系统,其内置的定时器功能支持高精度、灵活配置,适用于周期性或单次任务。

  • 步骤1:创建服务单元文件(定义要执行的任务)
    例如,创建/etc/systemd/system/myscript.service,内容如下(替换为实际脚本路径):
    [Unit]
    Description=My Custom Script Service
    
    [Service]
    Type=oneshot  # 单次任务(周期性任务可设为simple或其他类型)
    ExecStart=/path/to/your/script.sh  # 要执行的命令或脚本
    
  • 步骤2:创建定时器单元文件(定义超时/触发规则)
    例如,创建/etc/systemd/system/myscript.timer,内容如下(以“每天8点执行”为例):
    [Unit]
    Description=Run My Script daily at 8:00 AM
    
    [Timer]
    OnCalendar=*-*-* 08:00:00  # 每天8点触发(支持cron语法)
    Persistent=true  # 若错过计划时间,系统启动后会尽快补执行
    
    [Install]
    WantedBy=timers.target  # 启用后随系统启动
    
  • 步骤3:启用并启动定时器
    sudo systemctl daemon-reload  # 重新加载配置
    sudo systemctl enable myscript.timer  # 开机自启
    sudo systemctl start myscript.timer  # 立即启动
    
  • 查看定时器状态
    sudo systemctl status myscript.timer  # 查看下一次触发时间
    journalctl -u myscript.service -f  # 实时查看执行日志
    

说明

  • OnCalendar支持多种时间格式(如*-*-* 12:00:00表示每天中午12点,Mon *-*-* 09:00:00表示每周一9点)。
  • 若需周期性任务,可将OnCalendar改为OnUnitActiveSec(如OnUnitActiveSec=10sec表示每10秒触发一次)。

2. 使用timerfd(应用层定时器,适用于编程场景)

timerfd是Linux提供的文件描述符定时器,可通过编程实现高精度超时控制(适用于C/C++等语言)。

  • 示例代码(C语言)
    #include <sys/timerfd.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <time.h>
    
    int main() {
        // 1. 创建定时器文件描述符
        int fd = timerfd_create(CLOCK_MONOTONIC, 0);  // CLOCK_MONOTONIC为单调时间(不受系统时间修改影响)
        if (fd == -1) {
            perror("timerfd_create failed");
            return 1;
        }
    
        // 2. 设置定时器超时时间(第一次5秒,之后每3秒一次)
        struct itimerspec new_timer;
        new_timer.it_value.tv_sec = 5;  // 第一次超时时间(秒)
        new_timer.it_value.tv_nsec = 0; // 纳秒部分
        new_timer.it_interval.tv_sec = 3;  // 间隔时间(秒)
        new_timer.it_interval.tv_nsec = 0;
    
        if (timerfd_settime(fd, 0, &new_timer, NULL) == -1) {
            perror("timerfd_settime failed");
            close(fd);
            return 1;
        }
    
        // 3. 循环读取超时事件(每次超时会返回8字节数据,表示超时次数)
        uint64_t exp;
        while (1) {
            ssize_t s = read(fd, &exp, sizeof(exp));
            if (s != sizeof(exp)) {
                perror("read failed");
                break;
            }
            printf("Timer expired %llu times\n", (unsigned long long)exp);
        }
    
        close(fd);
        return 0;
    }
    
  • 编译与运行
    gcc -o timerfd_example timerfd_example.c
    ./timerfd_example
    
    输出示例:
    Timer expired 1 times  # 5秒后
    Timer expired 1 times  # 3秒后(第二次)
    Timer expired 1 times  # 3秒后(第三次)
    ...
    

说明

  • it_value:设置第一次超时时间(若为0则表示立即触发)。
  • it_interval:设置间隔时间(若为0则表示一次性定时器)。
  • CLOCK_MONOTONIC:推荐使用,避免系统时间修改影响定时精度。

3. 使用内核定时器(驱动/底层开发场景)

若需在内核模块中实现定时器(如驱动开发),可使用timer_list结构体。

  • 示例代码(内核模块)
    #include <linux/module.h>
    #include <linux/timer.h>
    #include <linux/jiffies.h>
    
    struct timer_list my_timer;
    
    void my_timer_callback(struct timer_list *timer) {
        printk(KERN_INFO "Timer expired!\n");
        // 重新设置定时器(实现周期性触发,若需一次性则无需此行)
        mod_timer(timer, jiffies + msecs_to_jiffies(2000));  // 2秒后再次触发
    }
    
    static int __init my_init(void) {
        printk(KERN_INFO "Module loaded\n");
        timer_setup(&my_timer, my_timer_callback, 0);  // 初始化定时器
        mod_timer(&my_timer, jiffies + msecs_to_jiffies(5000));  // 5秒后首次触发
        return 0;
    }
    
    static void __exit my_exit(void) {
        del_timer(&my_timer);  // 删除定时器
        printk(KERN_INFO "Module unloaded\n");
    }
    
    module_init(my_init);
    module_exit(my_exit);
    MODULE_LICENSE("GPL");
    
  • 编译与加载
    编写Makefile编译模块,使用insmod加载,rmmod卸载。
    加载后,通过dmesg查看内核日志,会看到“Timer expired!”的输出(每2秒一次)。

说明

  • jiffies:内核时间单位(节拍数),msecs_to_jiffies()用于将毫秒转换为节拍数。
  • mod_timer():用于修改定时器的超时时间(若定时器未激活则激活)。

4. 传统工具cron(仅适用于周期性任务)

cron是Ubuntu的周期性任务调度工具,但最小时间间隔为1分钟,无法实现秒级超时。

  • 步骤1:编辑当前用户的crontab
    crontab -e
    
  • 步骤2:添加定时任务(例如每天8点执行脚本)
    0 8 * * * /path/to/your/script.sh
    
  • 说明
    cron的语法为分钟 小时 日 月 周 命令,不支持秒级精度。

总结

  • 日常任务:优先使用systemd定时器(灵活、易管理)。
  • 编程场景:使用timerfd(高精度、与应用层集成)。
  • 内核开发:使用timer_list(底层驱动需求)。
  • 传统任务cron(仅适用于分钟级周期性任务)。

根据具体需求选择合适的方法,即可实现Ubuntu系统中的定时器超时设置。

0