程式設到 crontab 去執行是很常做的事情, 通常也會避免同時執行過多的 Script, 不過, 通常最怕的是程式要執行很久, 結果遇到程式還沒執行結束, 同樣的程式又被執行了一隻的狀況.
通常有幾種做法:
- 把時間拉長避開
- 程式寫 file.lock / ps 等, 去判斷是否執行結束
- 使用 lockf 來判斷
註: 關於 lockf 安裝可見 - 於 Debian Linux 安裝 lockf 或 參考 flock 用法
把時間拉長避開
預計此程式要跑 30 mins, 那就把 Crontab 設定最少差距 1hr 再執行.
程式寫 file.lock / ps 等, 去判斷是否執行結束
比較常用的做法會是於程式開始前 file.lock 等檔案, 然後於程式結束去刪掉此檔, 範例程式大致如下:
<?php
$lock_file = '/tmp/function.lock';
file_exists($lock_file) ? exit :touch($lock_file)
;
// todo something...
if (file_exists($lock_file)) {
unlink($lock_file);
}
?>
使用 lockf 來判斷
lockf 本身就有做這些機智, 直接看範例即可.
程式 sleep.php:
<?php
sleep(1000);
?>
執行:
- lockf -s -t 0 /tmp/sleep.lock /usr/bin/php sleep.php
- lockf -s -t 0 /tmp/sleep.lock /usr/bin/php sleep.php # 此程式不會被執行.
lockf 參數
lockf 參數就下述幾個:
- -k: 一直等到程式執行結束後才執行.
- -s: silent, 不要發出任何訊息, 即使拿不到 lock.
- -t seconds: 要等多久 timeout, 如果 timout 程式就不會被執行.
flock 參數(Linux 預設用 flock)
- flock [-sxon][-w #] file [-c] command...
- flock -w 0 /dev/null -c ./test.sh # -s read lock, -x write lock (預設是 -x)