Разделение процессов в 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 шт):

Автор решения: Jarry Roxwell

Ошибка невнимательного первокурсника, или кого хуже:

# НЕПРАВИЛЬНО
...
$result = [];
foreach ($Meow->runner() as $val) {
  $pids = []; /* <--- каждый раз обнуляется т.о. создается
      не 5 процессов, а равное количеству итераций runner`a */
  $maxProcesses = 5;
...

# ВЕРНО
...
$result = [];
$pids = [];
foreach ($Meow->runner() as $val) {
  $maxProcesses = 5;
...

Можно закрывать

→ Ссылка