fork порождение процессов

BoBka-altRUist

Новичок
fork порождение процессов

расскажите пожалуйста как работает pcntl

я так понимаю если мне нужно запустить скрипт sub.php в несколько дочерних процессов, и чтобы
их контролировал родительский main.php мне нужно использовать pcntl

в мануале смотрел (в поиске тоже, но в основном народ приходил к решению использовать что-то другое)
но вот в этом примере (это пример с php.net):

PHP:
<?php
declare(ticks=1);

$pid = pcntl_fork();
if ($pid == -1) {
     echo "could not fork\n";
     die("could not fork");
} else if ($pid) {
     echo "we are the parent\n";
     exit(); // we are the parent
} else {
     echo "we are the child\n";
     sleep(15);
     // we are the child
}

// detatch from the controlling terminal
if (posix_setsid() == -1) {
    die("could not detach from terminal");
}

// setup signal handlers
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");

// loop forever performing tasks
while (1) {
    echo "do something interesting here\n";
    sleep(8);
    // do something interesting here

}

function sig_handler($signo)
{

     switch ($signo) {
         case SIGTERM:
             // handle shutdown tasks
             echo "handle shutdown tasks\n";
             exit;
             break;
         case SIGHUP:
             // handle restart tasks
             echo "handle restart tasks\n";
             break;
         default:
             // handle all other signals
             echo "handle all other signals\n";
     }

}

?>
мне не ясно как тут работают сигналы
почему не происходит вызова функции sig_handler ?
и для чего функция posix_setsid ?

нашел еще одно описание которое получше того что на php.net
вот: http://www.electrictoolbox.com/article/php/process-forking/

пример оттуда:

PHP:
$pids = array();

for($i = 0; $i < 3; $i++) {

  $pids[$i] = pcntl_fork();
  echo $pids[$i]."\n";

	if ($pids[$i] == -1) {
	     echo "could not fork\n";
	     die("could not fork");
	} else if ($pids[$i]) {
	     echo "we are the parent\n";
	     //exit(); // we are the parent
	} else if(!$pids[$i]) {
	    // child process
	    echo "child process\n";
	    //...
	    echo "i am proc ".$i." - ".$pids[$i]."\n";
	    sleep(rand(5,10));
	    exit();
  	}



}


for($i = 0; $i < 3; $i++) {
  pcntl_waitpid($pids[$i], $status, WUNTRACED);
}


echo "complete parent processing now all children have finished\n";

...
все хорошо но, когда происходит вызов pcntl_waitpid то родительский процесс ждет завершения
этого процесса, после его завершения ждет завершения второго, и потом третьего,
а вдруг первый - самый длительный...
тут по идее должны помочь те сигналы которые бы сообщали о завершении какого-то процесса и можно было ему давать новое задание.

у меня такое ощущение что на pcntl разработчики забили или все используют другие решения, потому как на php.net ни комментариев не примеров...

да, еще, я могу передавать из дочерних процессов в родительский значение каких-либо переменных?
вот еще решение http://github.com/danhen/php_threads/tree/master но похоже до сих пор нестабильное (и мне все же хотелось узнать о pcntl)
 

whirlwind

TDD infected, paranoid
Прежде чем юзать надо бы почитать про IPC. Ну если по простому то setsid превращает процесс в демона, waitpid вычищает зомби. Форк полностью копирует процесс со всеми хендлерами потоков. Если рассуждать логически, то нет никакого смысла что то возвращать родительскому процессу. Если ты настаиваешь что тебе это нужно, то это уже клиент-сервер со всеми вытекающими сложностями.

PS. pcntl это не решение, это тупо интерфейс к системной либе. php не лучший выбор для системного программирования. Для этого лучше подходит perl, c или java с ее встроенной многопоточностью. по этому и забили
 

BoBka-altRUist

Новичок
ну впринципе об этом написано тут http://www.electrictoolbox.com/article/php/process-forking/
я специально не написал ни слова о ни о какой многопоточности ;)
(чтобы не появилась куча людей с пеной у рта утвержающих что нет многопоточности в php)
мне не нужны предложения юзать perl, java если бы они были нужны я бы их использовал, и тогда бы я задавал впорос не на phpclub ;)

о возможности получить значение переменной я только спросил, нельзя ну и ладно, а вот получить информацию о завершившемся потомке наверняка можно иначе в чем смысл такого интерфейса
 

whirlwind

TDD infected, paranoid
Я реально непонимаю людей которыю сцут изучить наиболее подходящий под задачу язык. Насчет пены - Советую обнаружить разницу между потоками и процессами. Ява была приведена как пример языка с очень удобной встроенное реализацией многопоточности, что как правило нужно в случае обмена данными в рамках одной программы, параллельно выполняющей несколько задач. Я просто уверен, что для человека реально нуждающемся в ipc нет ну абсолютно никакой сложности изучить какую-то там яву (перл песня отдельная - все таки оно писано лингвистом). Получить значение переменной можно. Но это - операция на гландах через жопу. Получить информацию о потомке можно. Т.к. pcntl это posix, велкам ту unix. В манах вся информация о потомках и о том как эту информацию можно получить. Маны на 99% для сишников.
 

cDLEON

Онанист РНРСlub
ну возьми, да создавай временные файлы с этими пидами.
А при завершении - удаляй их. В чём проблема?
 

whirlwind

TDD infected, paranoid
PS. что бы ты не терял свое время... о потомке можно получить только код и сигнал завершения, а так же проверить сам факт завершения. больше ничего с помощью посикса ты не узнаешь/
 

cDLEON

Онанист РНРСlub
Я реально непонимаю людей которыю сцут изучить наиболее подходящий под задачу язык.
Мне, кажется, в данном случае играет не очко, а нежелание\невозможность тратить время :)
 

dimagolov

Новичок
Автор оригинала: cDLEON
Мне, кажется, в данном случае играет не очко, а нежелание\невозможность тратить время :)
это как раз глупость. потому что во-первых никогда знания не бывают лишними, а во-вторых тут есть потребность именно в таких знаниях. что же касается времени, то сильно не уверен, что изучение-написание-отладка-внедрение демона на PHP будет принципаиально (то есть в разы) меньше, чем то же самое на C, даже если до этого опыта написания прог на C и не было. так как pcntl это просто маппер системного интерфеса и он на С выглядит так же само.
 

berkut

Новичок
изучение-написание-отладка-внедрение демона на PHP будет принципаиально (то есть в разы) меньше, чем то же самое на C
бред то какой... некоторые по специальности не учились - самоучки и даже тупо синтаксиса ц не знают... а помимо синтаксиса там ёптваюмать различий... даже банально компиляторы и их особенности
 

cDLEON

Онанист РНРСlub
dimagolov
В СИ есть указатели. Я изучал указатели несколько недель :)
(Имеется ввиду время на обучение программированния ими на автомате) Помню ещё тему здесь создавал....
Да и то... СИ очень трудно учить самому. Без наставников...
Для этого нужна база - у меня она была...
это как раз глупость
Не соглашусь. Иногда нужна заплатка, пусть и временная. Очень быстро. А другого языка ты не знаешь...

-~{}~ 02.04.09 23:54:

berkut
Ну вот - лицезрей. Самоучка собственной персоны - cDLEON - аплодисменты.
Но, как я уже сказал, это не одного дня дело - въехать в СИ, зная что то вроде делфы, ПХП, да паскаля....
 

Krishna

Продался Java
whirlwind
Какие преимущества у перла перед пыхом в контексте многопроцессных приложений?
 

dimagolov

Новичок
Но, как я уже сказал, это не одного дня дело - въехать в СИ, зная что то вроде делфы, ПХП, да паскаля....
хм... может быть. C для меня был 2-м ЯП. после Basic. перед Asm x86. в глубоком детстве :)
 

whirlwind

TDD infected, paranoid
Что то мне подсказывает что перейти с пхп на с проще нежели наоборот. Указатели аналогично референсам в пыхе, надо научиться только делейту. Зато ни один сишник не вкурит сходу что нужно в программном блоке специально декларировать переменные с глобальной областью видимости. прототипы писать научит компилятор, а вот пых и глазом не моргнет в этом плане - все на откуп раздолбаю-программисту.
 

Alexandre

PHPПенсионер
Для этого лучше подходит perl, c или java с ее встроенной многопоточностью. по этому и забили
для этого лучше всего подходит Си

вообще-то fork в пхп - это ни кому не нужное извращение
когда я это понял - мне понадобилась неделя, чтоб написать необходимый алгоритм на сях :)
иначе лучше не упоминать про многопоточность, потому-что от нее эффекта как от козла молока
 

whirlwind

TDD infected, paranoid
Alexandre это как сказать. вот например vuze работает на любой оське где ява есть, а сетсид тока на посиксе.
 

Alexandre

PHPПенсионер
Дим
посика для реализации большинства задач вполне достаточно
и вообще книга Ричарда Стивенса является у меня - настольной
 

BoBka-altRUist

Новичок
млин началось...

не спорю Perl круче! вы счастливы?

whirlwind: Я реально непонимаю людей которыю сцут изучить наиболее подходящий под задачу язык
вы психотерапевт? зачем вам понимать? я задаю конкретный вопрос по pcntl более ничего... (не порождайте офтопик бесцельными предложениями) не вижу смысла изучать для простой задачи дополнительный язык, тем более что есть решения на эхатаге.

whirlwind Советую обнаружить разницу между потоками и процессами.
заметьте про потоки вы начали говорить, я о них ни слова не сказал и не утверждал что где-то есть многопоточность а где-то ее нет :D (у вас похоже мания - всем говорить про то что в perl и java есть многопоточность Krishna подтвердит)

cDLEON: ну возьми, да создавай временные файлы с этими пидами.
спасибо, вариант, но я тут нашел хорошую доку: http://www.tuxradar.com/practicalphp/16/1/1
короче во втором коде в функции:

pcntl_waitpid($pids[$i], $status, WUNTRACED);

используется третий параметр WUNTRACED из-за него функция ждет завершения процесса, но можно использовать параметр WNOHANG,
сделать так (заменить строчку с pcntl_waitpid на этот кусок):

PHP:
while (1) {
    sleep(2);
    // do something interesting here

for($i = 0; $i < 3; $i++) {       
  echo $i . " - " . pcntl_waitpid($pids[$i], $status, WNOHANG) . "\n";
}
}
и если с другого терминала в момент запуска скрипта просмотреть что там с процессами
ps -ef | grep -v grep | grep php

при отработке видно, пока дочерний процесс выполняется функция pcntl_waitpid возвращает 0
когда процесс завершился функция pcntl_waitpid возвращает pid этого процесса (который отображался во втором терминале)
и когда его нет функция pcntl_waitpid возвращает -1

ну возможно я немного не так описал, но суть в том, что когда процесс отработал то возвращается -1 и его снова можно нагружать.

з.ы. ну и для последователей: почему не работали сигналы из первого примера с php.net, они работают просто они "сигнализируют" по завершении процесса по Ctrl+C это SIGINT , kill "pid" - это SIGTERM .

Ну и др. системные вызовы которые отправляют SIGHUP процессу:

kill -HUP <process>
kill -SIGHUP <process>
kill -1 <process>

kill -TERM <process>
kill -SIGTERM <process>
kill -15 <process>
 

Krishna

Продался Java
Указатели аналогично референсам в пыхе, надо научиться только делейту.
Ересь, кстати. Указатели и ссылки - совсем не одно и то же, не надо нубов смущать.
 
Сверху