Ваш пример не затрагивает проблемы, которые вы можете решить с помощью pcntl_fork.
Помните, что fork () создает копию программы, что означает, что все дескрипторы скопированы. К сожалению, это довольно плохая ситуация для программы PHP, потому что большинство дескрипторов обрабатываются PHP или расширением PHP внутри.
Простой и, вероятно, "правильный" способ решения этой проблемы - это разветвление заранее, в действительности не должно быть необходимости разветвляться во многих различных точках программы, вы просто разветвляетесь, а затем делегируете работу. Используйте основную / рабочую иерархию.
Например, если вам нужно иметь много процессов, использующих MySQL Connection, просто выполните разветвление перед установлением соединения, чтобы каждый дочерний процесс имел свое собственное соединение с mysql, которым он управляет, и только он этим управляет.
Еще одна вещь, на которую следует обратить внимание, это когда умирает дочерний процесс. Это смерть должна быть обработана родителем. Если это не так, ребенок становится зомби: он не потребляет ресурсы, но все равно это процесс с PID и всем этим. Это нежелательно, поскольку большинство (все?) Операционных систем имеют верхний предел процессов, которые он может обрабатывать.
Когда умирает ребенок, родитель посылает сигнал (SIGCHLD). Затем родитель может обработать смерть ребенка для внутренней обработки. Правильный способ разомкнуть ребенка - использовать pcntl_waitpid (). Вы можете использовать эту функцию, чтобы дождаться смерти ребенка или обнаружить, что ребенок уже умер. Используйте pcntl_wait (), когда вы хотите сделать это для множества детей. Посмотрите в соответствующем разделе руководства по PHP дополнительные параметры (включая указание функции не прерывать нормальную работу).
Однако использование SIGCHLD не всегда надежно. Когда вы быстро создаете много недолговечных потомков, обработка SIGCHLD в сочетании с pcntl_waitpid () может не обрабатывать все процессы зомби.
Надеюсь, это помогло, документация на php.net в порядке, но, на мой взгляд, она могла бы пойти глубже в предметах и потенциальных ловушках, поскольку эти функции легко злоупотреблять.
Вот тривиальный пример (извлечен из комментария php.net) , который показывает неправильное распределение ресурсов для родительского потока:
<?php
mysql_connect(/* enter a working server here maybe? */);
$f=pcntl_fork();
while(true){
sleep(rand(0,10)/100);
$r=mysql_query("select $f;");
if(!$r)die($f.": ".mysql_error()."\n");
list($x)=mysql_fetch_array($r);
echo ($f)?".":"-";
if($x!=$f) echo ($f.": fail: $x!=$f\n ");
}
?>
Выполнение этой команды на cli приведет к различным результатам:
очень часто просто зависает и больше ничего не выводит
также очень часто сервер закрывает соединение, возможно потому, что он получает чередующиеся запросы, которые он не может обработать.
иногда один процесс получает результат ДРУГИХ процессов
запрос! (потому что оба посылают свои запросы по одному сокету,
и это просто удача, кто получит ответ)
Надеюсь, это поможет, если вы расширите свой пример для извлечения данных и / или использования ресурсов.
С праздником!