2012-01-26 9 views
17

Mam kod, który jest trochę tak:Wywołanie funkcji w wątku tła/procesu (rozwidlone)

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

Powyższe jest czasochłonne zadanie, i miałem nadzieję, aby móc utworzyć funkcję, i nazywają go dwa razy jak poniżej

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

Spojrzałem na gearman ale nie mogę go używać, ponieważ nie można zainstalować serwer gearman (ponieważ jestem na wspólnym serwerze). Wydaje się, że sposobem na osiągnięcie tego byłoby rozwidlenie. Próbowałem dużo czytać na ten temat, ale dokumentacja i wsparcie są znikome. Przydałaby się każda pomoc/kod szkieletowy.

Aby zdefiniować moje pytanie, w jaki sposób mogę wywołać wrapper() przekazując argumenty takie, że są wykonywane w procesie potomnym. Ponadto ważne jest, aby móc zarejestrować funkcję zwrotną.

Dodatkowe szczegóły: PHP 5.3, działające na serwerze Linux. Skrypt jest wykonywany przez cgi-fcgi.

Myślę, że w ten sposób mam odrodzić proces potomny, ale w jaki sposób mogę go użyć do odrodzenia wielu procesów podrzędnych? A jak zarejestrować funkcję zwrotną?

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

Odpowiedz

9

Od "profesjonalnego bloga Tudor Barbu za"
(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

Dzięki. Wygląda to jak genialne opakowanie. Zajmuję się teraz kodem – xbonez

+1

Link, do którego się odwołujesz, mówi także, że źle jest używać pustej pętli do sprawdzenia, czy wątki są żywe, ponieważ wykorzystają cały procesor. Powinieneś dołączyć do snu w pętli. – Kelvin

+0

@ Kelvin, lepszym rozwiązaniem jest zaimplementowanie funkcji 'join' w bibliotece, powinno być dość proste. –

2

Jeśli używasz Linuksa można skorzystać z linii poleceń i zrobić

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

Spowoduje to utworzenie nowej instancji PHP w tle i odłączenie się od funkcji exec w głównym wątku.

Ostrzeżenie: Jedynym minusem jest to, że nie można kontrolować, co robią te wątki po ich utworzeniu.