2012-01-26 11 views
17

tengo código que es algo así como esto:Llamar a una función en un subproceso de fondo/proceso (bifurcar)

($i=0; $i < 100; $i++) 
{ 
    do ($foo[$i]); 
} 

Lo anterior es una tarea intensiva de tiempo, y yo tenía la esperanza de ser capaz de crear una función, y llamar dos veces, como a continuación

function wrapper($start;$end) 
{ 
    ($i=$start; $i < $end; $i++) 
    { 
     do ($foo[$i]); 
    } 
} 
//have both of these run in parallel 
wrapper(0,50); 
wrapper(51,100); 

miré Gearman pero no puedo usarlo ya que no puedo instalar el servidor gearman (ya que estoy en un servidor compartido). Parece que la forma de lograr esto sería bifurcando. Intenté leer mucho al respecto, pero la documentación y el soporte son escasos. Cualquier código de ayuda/wireframe sería apreciado.

Para definir mi pregunta, ¿cómo podría llamar a wrapper() pasando los argumentos de manera que se ejecute en un proceso secundario? Además, es importante que pueda registrar una función de devolución de llamada.

Detalles adicionales: PHP 5.3, ejecutándose en el servidor Linux. El script es ejecutado por cgi-fcgi.

Creo que así es como se supone que debo engendrar un proceso secundario, pero ¿cómo puedo usarlo para engendrar múltiples procesos hijo? ¿Y cómo registro una función de devolución de llamada?

$pid = pcntl_fork(); 

if ($pid == -1) {   
    // Fork failed    
    exit(1); 
} else if ($pid) { 
    // The parent process 
    //should I repeat this same code here to spawn another child process? 

} else { 
    // the child process 
    //can I call wrapper from here and will it run in this child process? 

Respuesta

9

De "blog profesional de Tudor Barbu"
(http://blog.motane.lu/2009/01/02/multithreading-in-php/)

require_once('Thread.php'); 

// test to see if threading is available 
if(! Thread::isAvailable()) { 
    die('Threads not supported'); 
} 

// function to be ran on separate threads 
function paralel($_limit, $_name) { 
    for ($index = 0; $index < $_limit; $index++) { 
     echo 'Now running thread ' . $_name . PHP_EOL; 
     sleep(1); 
    } 
} 

// create 2 thread objects 
$t1 = new Thread('paralel'); 
$t2 = new Thread('paralel'); 

// start them 
$t1->start(10, 't1'); 
$t2->start(10, 't2'); 

// keep the program running until the threads finish 
while($t1->isAlive() && $t2->isAlive()) { 

} 

Download Thread.php

+0

Gracias. Esto parece una envoltura brillante. Estoy investigando el código en este momento – xbonez

+1

El enlace al que hace referencia también dice que es malo usar un bucle vacío para verificar si los hilos están vivos, porque usará toda su CPU. Deberías incluir un sueño en el ciclo. – Kelvin

+0

@ Kelvin, una mejor solución es implementar una capacidad de 'unirse' a la biblioteca, debería ser bastante simple de hacer. –

2

Si está utilizando Linux se puede tomar ventaja de la línea de comandos y hacer

public function newWrapperInstance($start,$end){ 
    exec('bash -c "exec nohup setsid php-cli yourFile.php '.$start.' '.$end.' > /dev/null 2>&1 &"'); 
} 

Esto creará una nueva instancia de PHP en el fondo y se separará de la función ejecutiva en el hilo principal.

Advertencia: El único inconveniente es que no puede controlar lo que hacen esos hilos una vez que se han creado.

Cuestiones relacionadas