於 Linux、FreeBSD 使用 lockf 避免程式未結束,又被再次執行

程式設到 crontab 去執行是很常做的事情, 通常也會避免同時執行過多的 Script, 不過, 通常最怕的是程式要執行很久, 結果遇到程式還沒執行結束, 同樣的程式又被執行了一隻的狀況.

通常有幾種做法:

  1. 把時間拉長避開
  2. 程式寫 file.lock / ps 等, 去判斷是否執行結束
  3. 使用 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);
?>

執行:

  1. lockf -s -t 0 /tmp/sleep.lock /usr/bin/php sleep.php
  2. 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)

關於 Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.
本篇發表於 My_Note-Unix。將永久鏈結加入書籤。

於 Linux、FreeBSD 使用 lockf 避免程式未結束,又被再次執行 有 10 則回應

  1. 蒜頭 說道:

    我試了一下還真的是好用啊

  2. Tsung 說道:

    嗯嗯, 就是超方便, 所以我才努力找 Linux 版的支援囉~ 😛

  3. Fwolf 說道:

    程序中途异常退出有影响么?
    不然和自己写lock文件没什么区别。

  4. Tsung 說道:

    我測試 flock, 不會有影響.
    比自己寫 lock 文件穩定多囉~ 🙂

  5. Fwolf 說道:

    谢谢,回头我也试试。

  6. President 說道:

    $lcok_file 有錯字^^
    file_exists($lock_file) ? touch($lock_file) : exit; 順序顛倒~

  7. Tsung 說道:

    嗯嗯, 感謝指正, 已修復~ Orz..

  8. 王春 說道:

    sleep.lock 应该怎么写额,为什么我的还是可以执行呀。

  9. don 說道:

    flock是方便,但是如果程序非正常结束,flock并没有被解锁,然后。。。程序再也起不来了,只能重启电脑了

發表迴響