2011-08-10 73 views
9

我有一個index.php腳本,我在Google Code站點上用作提交後的URL。該腳本克隆目錄並構建可能需要一些工作的項目。我想避免讓這個腳本並行運行多次。如何確保我只有一個通過Apache運行的PHP腳本實例?

有沒有一種機制可以用來避免執行該腳本,如果另一個已經在會話中?

回答

21

您可以使用flockLOCK_EX獲得一個文件的獨佔鎖定。

例如爲:

<?php 
$fp = fopen('/tmp/php-commit.lock', 'r+'); 
if (!flock($fp, LOCK_EX | LOCK_NB)) { 
    exit; 
} 

// ... do stuff 

fclose($fp); 
?> 

對於5.3.2之後,你需要手動釋放使用 羊羣($ FP,LOCK_UN)鎖定的PHP版本;

+0

迄今爲止從未使用flock(),感謝您的答案! – powtac

+0

@LongEars提到這段代碼實際上是在Windows上運行另一個實例,因爲'LOCK_NB'根據'flock'上的PHP手冊不工作。它將等待'flock'直到先前的實例完成,然後運行整個代碼。 –

+0

此外,爲了確保它能夠按預期工作,您可能需要將fopen模式更改爲: '$ fp = fopen('/ tmp/php-commit.lock','c'); ' 如果commit.lock文件尚不存在,則使用'r +'會引發PHP錯誤。 – DoctorFox

1

只有當您保存運行腳本的狀態並檢查腳本何時啓動(如果其他腳本當前處於活動狀態)。

例如保存,如果一個腳本運行,你可以做這樣的事情:

$state = file_get_contents('state.txt'); 

if (!$state) { 
    file_put_contents('state.txt', 'RUNNING, started at '.time()); 

    // Do your stuff here... 

    // When your stuff is finished, empty file 
    file_put_contents('state.txt', ''); 
} 
1

需要多長時間才能運行。如果任務失敗,您將需要從內存緩存清除

可以使用內存緩存

<?php 
$m = new Memcache(); // check the constructor call 

if($m->get('job_running')) exit; 

else $m->set('job_running', true); 



//index code here 

//at the end of the script 

$m->delete('job_running'); 

?> 

。羊羣也是一個不錯的選擇......實際上可能會更好。

+1

爲了避免手動清除任務失敗,您可以根據任務運行時間的某個頂部邊界對集合使用時間限制。 – Noam

相關問題