我有一個index.php
腳本,我在Google Code站點上用作提交後的URL。該腳本克隆目錄並構建可能需要一些工作的項目。我想避免讓這個腳本並行運行多次。如何確保我只有一個通過Apache運行的PHP腳本實例?
有沒有一種機制可以用來避免執行該腳本,如果另一個已經在會話中?
我有一個index.php
腳本,我在Google Code站點上用作提交後的URL。該腳本克隆目錄並構建可能需要一些工作的項目。我想避免讓這個腳本並行運行多次。如何確保我只有一個通過Apache運行的PHP腳本實例?
有沒有一種機制可以用來避免執行該腳本,如果另一個已經在會話中?
您可以使用flock與LOCK_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版本;
只有當您保存運行腳本的狀態並檢查腳本何時啓動(如果其他腳本當前處於活動狀態)。
例如保存,如果一個腳本運行,你可以做這樣的事情:
$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', '');
}
需要多長時間才能運行。如果任務失敗,您將需要從內存緩存清除
可以使用內存緩存
<?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');
?>
。羊羣也是一個不錯的選擇......實際上可能會更好。
爲了避免手動清除任務失敗,您可以根據任務運行時間的某個頂部邊界對集合使用時間限制。 – Noam
迄今爲止從未使用flock(),感謝您的答案! – powtac
@LongEars提到這段代碼實際上是在Windows上運行另一個實例,因爲'LOCK_NB'根據'flock'上的PHP手冊不工作。它將等待'flock'直到先前的實例完成,然後運行整個代碼。 –
此外,爲了確保它能夠按預期工作,您可能需要將fopen模式更改爲: '$ fp = fopen('/ tmp/php-commit.lock','c'); ' 如果commit.lock文件尚不存在,則使用'r +'會引發PHP錯誤。 – DoctorFox