Linux cron 源碼剖析

TODO

背景及 busybox 介紹

BusyBox是一個遵循GPL協議、以自由軟件形式發行的應用程序。Busybox在單一的可執行文件中提供了精簡的Unix工具集,可運行於多款POSIX環境的操做系統,例如Linux(包括Android[6])、Hurd[7]、FreeBSD8等等。因爲BusyBox可執行文件的文件大小比較小、並一般使用Linux內核,這使得它很是適合使用於嵌入式系統。做者將BusyBox稱爲「嵌入式Linux的瑞士軍刀」git

BusyBox 內嵌了許多 Linux 經常使用的工具, cp,mv,cron 等。
這次分析 BusyBox 中的 cron 流程。原代碼在此github

流程圖

流程以下shell

main.png

1-2.png

1-3.png

數據結構

用戶輸入的 cron 配置通過解析後,存到以下兩個結構體中。c#

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分鐘。
相關文章
相關標籤/搜索