Разделение процессов в php
Собрал вот такой вот код для разделения процессов (class Meow тень того как работает реальный класс, главное, что и тот и Meow возвращают генератор):
class Meow
{
public function runner(): Generator
{
foreach (['helpme', 'макароны', 'картошка', 'морковка', 'яблоки', 'груша', 'слива', 'котлетка', 'колбаска', 'сосиска', 'чипсы', 'пиво', 'вино', 'джин', 'текила', 'оливки', 'начос', 'зажигалка', 'телефон', 'кольцо', 'rage',] as $v)
yield $v;
}
}
$LoopTime = microtime(true);
echo "START >> 0\n";
$Meow = new Meow();
$result = [];
foreach ($Meow->runner() as $val) {
$pids = [];
$maxProcesses = 5;
do {
while (count($pids) < $maxProcesses) {
$pid = pcntl_fork();
if ($pid == -1) {
die("Не удалось создать процесс.");
} elseif ($pid) {
$pids[] = $pid;
break;
} else {
/****************************************************** */
sleep(5);
$upperCaseVal = mb_strtoupper($val);
file_put_contents(__DIR__ . '/' . time() . '-' . rand(1, 100), $upperCaseVal);
// echo getmypid() . ' > ' . $upperCaseVal . PHP_EOL;
/****************************************************** */
exit(999);
}
}
foreach ($pids as $key => $pid) {
$result = pcntl_waitpid($pid, $status, WNOHANG);
if ($result == -1 || $result > 0) {
unset($pids[$key]);
}
}
$pids = array_values($pids);
usleep(100000);
#
} while (count($pids) == $maxProcesses);
}
$time = number_format(microtime(true) - $LoopTime, 4, '.', '');
echo "{$time}s >> END.\n";
С одной стороны он работает правильно создает 20 файлов с уперкейсом.
Ноо что очень смущает в консоле я вижу 2.1441s >> END.
, а значит делаю, что то не правильно. Выполняя в одно процессе время должно быть около 105 сек. (21*5
), однако делю 21 элемент на 5 процессов с задержкой по 5 секунд, на выходе должно быть примерно 25 сек. (5 процессов с задержкой на 5сек., 4 раза повторить, уже 20сек.и еще 5 на оставшийся элемент... просчитался, но где).
И вот я не понимаю почему родительский процесс завершается так быстро? И правда ли на момент завершения все завершилось.
Ответы (1 шт):
Ошибка невнимательного первокурсника, или кого хуже:
# НЕПРАВИЛЬНО
...
$result = [];
foreach ($Meow->runner() as $val) {
$pids = []; /* <--- каждый раз обнуляется т.о. создается
не 5 процессов, а равное количеству итераций runner`a */
$maxProcesses = 5;
...
# ВЕРНО
...
$result = [];
$pids = [];
foreach ($Meow->runner() as $val) {
$maxProcesses = 5;
...
Можно закрывать