2011-08-10 3 views
9

Google 코드 사이트에서 커밋 후 URL로 사용하는 index.php 스크립트가 있습니다. 이 스크립트는 디렉토리를 복제하고 작업을 수행 할 수있는 프로젝트를 만듭니다. 이 스크립트가 한 번 이상 병렬로 실행되는 것을 피하고 싶습니다.Apache를 통해 실행중인 PHP 스크립트의 인스턴스를 하나만 확보하려면 어떻게합니까?

다른 스크립트가 이미 세션에있는 경우 해당 스크립트 실행을 피할 수있는 메커니즘이 있습니까?

답변

21

당신은 파일에 대한 단독 잠금을 얻을 수 LOCK_EXflock를 사용할 수 있습니다. 수동 무리 ($ FP, LOCK_UN)를 사용하여 잠금을 해제 할 필요가 5.3.2 이후의 PHP 버전

예컨대 :

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

// ... do stuff 

fclose($fp); 
?> 

;

+0

지금까지 사용하지 않은 flock() 지금까지 답변 해 주셔서 감사합니다! – powtac

+0

@LongEars'LOCK_NB'가'flock'의 PHP 매뉴얼에 따라 작동하지 않기 때문에이 코드는 Windows에서 다른 인스턴스를 실제로 실행한다고 언급합니다. 이전 인스턴스가 끝날 때까지'flock'을 기다린 다음 전체 코드를 실행합니다. –

+0

또한 예상대로 작동하려면 fopen 모드를 '$ fp = fopen ('/ tmp/php-commit.lock', 'c');으로 변경하고 싶을 수 있습니다. ' 'r +'를 사용하면 commit.lock 파일이없는 경우 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

실행하는 데 시간이 오래 걸립니다. 작업은 당신이 memcache에에서 삭제해야합니다 실패하면

<?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'); 

?> 

memcache에 사용할 수 있습니다. 무리도 좋은 선택입니다. 아마 실제로는 더 좋습니다.

+1

작업 실패시 수동으로 지우는 것을 피하기 위해 작업 실행 시간의 일부 경계에 따라 시간 제한을 사용할 수 있습니다. – Noam

관련 문제