Вызов функции в фоновом потоке/процессе (разветвление)
У меня есть код, который выглядит примерно так:
($i=0; $i < 100; $i++)
{
do ($foo[$i]);
}
Вышеприведенная задача требует много времени, и я надеялся создать функцию и называть ее дважды, как показано ниже
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);
Я посмотрел на Gearman, но я не могу использовать его, поскольку я не могу установить сервер ретранслятора (так как я на общем сервере). Похоже, что достичь этого можно было бы путем разветвления. Я пробовал много об этом прокомментировать, но документация и поддержка скудны. Любой код помощи/каркаса будет оценен.
Чтобы определить мой вопрос, как я мог бы вызвать wrapper()
передачу в аргументах так, чтобы он выполнялся в дочернем процессе. Кроме того, важно, чтобы я мог зарегистрировать функцию обратного вызова.
Дополнительные сведения: PHP 5.3, работающий на сервере Linux. Script выполняется cgi-fcgi.
Я думаю, что именно так я должен порождать дочерний процесс, но как я могу использовать его для создания нескольких дочерних процессов? И как мне зарегистрировать функцию обратного вызова?
$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?
Ответы
Ответ 1
Из "Профессионального блога 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() ) {
}
Загрузить Thread.php
Ответ 2
Если вы используете Linux, вы можете воспользоваться командной строкой и сделать
public function newWrapperInstance($start,$end){
exec('bash -c "exec nohup setsid php-cli yourFile.php '.$start.' '.$end.' > /dev/null 2>&1 &"');
}
Это создаст новый экземпляр PHP в фоновом режиме и отделится от функции exec в основном потоке.
Предупреждение:
Единственным недостатком является то, что вы не можете контролировать, что эти потоки делают после их создания.