Linux cron 源码剖析

TODO

背景及 busybox 介绍

BusyBox是一个遵循GPL协议、以自由软件形式发行的应用程序。Busybox在单一的可执行文件中提供了精简的Unix工具集,可运行于多款POSIX环境的操作系统,例如Linux(包括Android[6])、Hurd[7]、FreeBSD8等等。由于BusyBox可执行文件的文件大小比较小、并通常使用Linux内核,这使得它非常适合使用于嵌入式系统。作者将BusyBox称为“嵌入式Linux的瑞士军刀”

BusyBox 内嵌了许多 Linux 常用的工具, cp,mv,cron 等。
此次分析 BusyBox 中的 cron 流程。原代码在此

流程图

流程如下

Linux cron 源码剖析

Linux cron 源码剖析

Linux cron 源码剖析

数据结构

用户输入的 cron 配置经过解析后,存到如下两个结构体中。

typedef struct CronFile {
    struct CronFile *cf_next;
    struct CronLine *cf_lines;
    char *cf_username;
    smallint cf_wants_starting;     /* bool: one or more jobs ready */
    smallint cf_has_running;        /* bool: one or more jobs running */
    smallint cf_deleted;            /* marked for deletion (but still has running jobs) */
} CronFile;

typedef struct CronLine {
    struct CronLine *cl_next;
    char *cl_cmd;                   /* shell command */
    pid_t cl_pid;                   /* >0:running, <0:needs to be started in this minute, 0:dormant */
#define START_ME_REBOOT -2
#define START_ME_NORMAL -1
#if ENABLE_FEATURE_CROND_CALL_SENDMAIL
    int cl_empty_mail_size;         /* size of mail header only, 0 if no mailfile */
    char *cl_mailto;                /* whom to mail results, may be NULL */
#endif
    char *cl_shell;
    /* ordered by size, not in natural order. makes code smaller: */
    char cl_Dow[7];                 /* 0-6, beginning sunday */
    char cl_Mons[12];               /* 0-11 */
    char cl_Hrs[24];                /* 0-23 */
    char cl_Days[32];               /* 1-31 */
    char cl_Mins[60];               /* 0-59 */
} CronLine;

cron 使用方法

分析

  • 由于 cron 的时间同步机制问题,两次任务间隔并不一定准确。举例,假设设定了每分钟运行一次的定时任务,在10:10:56 开始执行。那么根据它的时间同步对齐机制,下次将在 10:11:00 执行,就是中间只隔了4秒,再下一次是 10:12:00 就恢复正常了。
  • Linux 自带的 cron 是基于绝对时间的。什么意思呢,就是运行任务的时间差是基于 NTP 的。如果你的 NTP 挂了,或是手动调整了时间,会影响定时任务的运行。如果调整的时间超过了1小时, cron 将报错,本次 loop 不执行。
  • cron 定时任务定义的最小时间间隔为1分钟。

相关推荐