2011-08-10 10 views
9

Tengo un script index.php que utilizo como una URL posterior a la confirmación en un sitio de Google Code. Esta secuencia de comandos clona un directorio y crea un proyecto que puede tomar algún trabajo. Quiero evitar que este script se ejecute más de una vez en paralelo.¿Cómo puedo asegurarme de tener solo una instancia de un script PHP ejecutándose a través de Apache?

¿Existe un mecanismo que pueda usar para evitar ejecutar ese script si ya hay otro en sesión?

Respuesta

21

Puede utilizar flock con LOCK_EX para ganar un bloqueo exclusivo en un archivo.

ej .:

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

// ... do stuff 

fclose($fp); 
?> 

Para las versiones de PHP 5.3.2 después de que necesita para liberar manualmente la cerradura usando rebaño ($ fp, LOCK_UN);

+0

rebaño nunca utilizado() hasta el momento, gracias por la respuesta! – powtac

+0

@LongEars Mencione que este código realmente ejecuta otra instancia en Windows, ya que 'LOCK_NB' no funciona allí de acuerdo con el manual de PHP en' flock'. Esperará en 'flock' hasta que las instancias anteriores finalicen, y luego ejecutará todo el código. –

+0

Además, para garantizar que esto funcione como se espera, puede cambiar el modo fopen a: '$ fp = fopen ('/ tmp/php-commit.lock', 'c'); ' Usar 'r +' arrojaría un error de PHP si el archivo commit.lock aún no existe. – DoctorFox

1

Solo si guarda el estado de la secuencia de comandos en ejecución y comprueba cuándo se inicia la secuencia de comandos si otra secuencia de comandos está actualmente activa.

Por ejemplo, si para guardar una secuencia de comandos se está ejecutando se podría hacer algo como esto:

$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

cuánto tiempo se tarda en ejecutarse.

podría utilizar 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'); 

?> 

Si la tarea no tendrá que borrar de Memcache. Flock es una buena opción también ... probablemente mejor en realidad.

+1

Para evitar el borrado manual de la falla de la tarea, puede usar un límite de tiempo para el conjunto de acuerdo con algún límite superior del tiempo de ejecución de la tarea. – Noam

Cuestiones relacionadas