2010-06-26 260 views
1

我試圖阻止我的cron腳本允許它並行運行。我需要它,以便如果當前沒有執行它,腳本將被允許運行直到它完成,腳本超時或發生異常。停止並行執行PHP腳本

我一直在嘗試使用PHP flock函數進行文件鎖定,運行腳本並釋放鎖定。但是,它仍然看起來像我能夠並行運行腳本多次。我錯過了什麼嗎?

順便說一句,我正在開發與Mac文件系統的Mac OS X,也許這是文件鎖被忽略的原因?雖然PHP文檔只看起來關於NTFS文件系統?

 // Construct cron lock file path 
    $cronLockFilePath = realpath(APPLICATION_PATH . '/locks/cron'); 

    // Get cron lock file 
    $cronLockFile = fopen($cronLockFilePath, 'r'); 

    // Lock cron lock file 
    if (flock($cronLockFile, LOCK_EX)) { 

echo 'lock'; 
sleep(10); 

    } else { 

echo 'no lock'; 
    } 

回答

3

你的想法基本上是正確的,但修補文件鎖通常會導致奇怪的行爲。

只需在腳本啓動時創建一個文件並在最後刪除它。文件的存在將指示cron是否已經在運行。確保文件在最後被刪除,即使cron中途遇到錯誤。

+0

處理錯誤不應該是一個問題,我只會捕獲所有異常,然後取消鏈接創建的文件...但我想象,處理腳本終止是不可能的,例如服務器重新啓動,apache重新啓動或腳本超時。 。因爲它是一個cron文件,我可能會讓腳本運行而不會超時。 – cappuccino 2010-06-26 08:08:44

+0

您可以嘗試使用兩個腳本:第一個創建「鎖定」文件,執行當前的cron腳本,然後刪除「鎖定」文件。所以即使你的當前cron腳本爆炸了,第一個腳本仍然會刪除鎖定。 我已經做過的另一件事是:如果腳本檢測到「lock」文件存在,但filectime超過一個小時,則繼續前進並將其刪除,因爲很可能出現問題。 – FlorianH 2010-06-26 09:43:40

0

我覺得你可以做的是寫一個普通文件的地方(lock.txt或東西),當腳本開始執行,沒有任何的羊羣,腳本停止運行時將其刪除。然後總是檢查初始化文件是否已經存在 - 另一個實例正在運行。

+0

文件存在和鎖文件創建檢查至少有兩個命令,這意味着它仍然有可能存在競爭條件。 'flock'不是沒有理由的。 – cweiske 2011-05-02 12:00:50

1

從文檔:

警告

在某些操作系統羣()是 在進程級實現。當 使用多線程服務器API(如 ISAPI)時,您可能無法依賴 flock()來保護文件免受其他 PHP腳本並行運行 同一服務器實例的線程!

您可以嘗試創建和刪除文件,或者寫入文件。

+0

我明白了,我看到了一些其他方法,它們依賴於創建文件然後刪除一次完成。然而,這不會能夠處理腳本超時和異常,其中腳本在執行解除鏈接功能之前被終止。因此,儘管腳本可能已被終止,但由於創建的文件尚未被刪除,腳本將無法再次運行。有沒有辦法處理這種情況? – cappuccino 2010-06-26 08:02:46

+0

首先想到的是,也許你可以嘗試打開套接字,而當其他線程試圖在同一端口上打開同一個套接字時,它們會失敗。 – codez 2010-06-26 08:12:12