2012-01-26 10 views
17

Ho codice che è un po 'come questo:Chiamare una funzione in un thread in background/processo (si biforcano)

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

Quanto sopra è un compito molto tempo, e speravo di essere in grado di creare una funzione, e chiamare due volte come qui di seguito

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

ho guardato Gearman ma non posso usarlo come non posso installare il server Gearman (dato che sono su un server condiviso). Sembra che il modo per ottenere questo sarebbe biforcarsi. Ho provato a leggerlo parecchio, ma la documentazione e il supporto sono scarsi. Qualsiasi aiuto/codice wireframe sarebbe apprezzato.

Per definire la mia domanda, come potrei chiamare wrapper() passando argomenti in modo che venga eseguito in un processo figlio. Inoltre, è importante che io sia in grado di registrare una funzione di callback.

Dettagli aggiuntivi: PHP 5.3, in esecuzione su server Linux. Lo script è eseguito da cgi-fcgi.

Penso che questo sia il modo in cui dovrei generare un processo figlio, ma come posso utilizzarlo per generare più processi figlio? E come posso registrare una funzione di callback?

$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? 

risposta

9

Da "blog professionale di 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

Grazie. Questo sembra un involucro brillante. Sto cercando il codice adesso – xbonez

+1

Il link che hai indicato dice anche che è male usare un ciclo vuoto per verificare se i thread sono vivi, perché userà tutta la tua CPU. Dovresti includere una sospensione nel ciclo. – Kelvin

+0

@Kelvin, una soluzione migliore è implementare una funzionalità 'join' nella libreria, dovrebbe essere abbastanza semplice da fare. –

2

Se si utilizza Linux è possibile usufruire della riga di comando e fare

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

Ciò creerà una nuova istanza di PHP in background e si disconnetterà dalla funzione exec nel thread principale.

Avviso: L'unico lato negativo è che non è possibile controllare ciò che fanno quei thread una volta creati.

Problemi correlati