PHP: как заставить родительский скрипт ждать завершения всех дочерних скриптов - PullRequest
0 голосов
/ 23 апреля 2020

Во время каждой итерации foreach l oop я хотел бы инициализировать фоновый процесс, используя функцию exe c для передачи файла json в рабочий сценарий. php.

Я хочу, чтобы каждый процесс, инициализированный функцией exe c, выполнялся параллельно. Я хочу, чтобы остальные операторы после foreach l oop в родительском скрипте ожидали фонового дочернего процесса и выполнялись только после завершения всех фоновых дочерних процессов. Как мне это сделать?

Вот мой php код:

foreach($inputDataGroups as $inputsForTask){
    $json_string_input = json_encode($inputsForTask);
    $filename = 'ImportApp_input_data_'.($group_no + 1).".json";
    file_put_contents($filename,$json_string_input);
    exec('php worker.php "' . $filename . '"'.' ImportApp');
    $group_no++;
}
$dbappList = $this->getImportAppNameByLocationId($LocationID);
return $dbappList;

Ответы [ 2 ]

0 голосов
/ 24 апреля 2020

Используя pcntl_fork, вы можете попробовать что-то вроде этого:

if (! function_exists('pcntl_fork')) {
  throw new \RuntimeException('PCNTL functions not available on this PHP installation');
}

$commands = [];
foreach($inputDataGroups as $inputsForTask){
  $json_string_input = json_encode($inputsForTask);
  $filename = 'ImportApp_input_data_'.($group_no + 1).".json";
  file_put_contents($filename,$json_string_input);
  $commands[] = 'php worker.php "' . $filename . '"'.' ImportApp';
  $group_no++;
}

// forking processes
$children = [];
foreach ($commands as $command) {
  switch($pid = pcntl_fork()) {
    case -1:
      throw new \Exception("Unable to fork process");
      break;
    case 0:
      // Child process
      exec($command, $output, $exitCode);
      // Child only need to execute command
      exit($exitCode);
    default:
      $children[] = $pid;
      break;
  }
}

// Waiting for children to finish
foreach ($children as $pid) {
  // We are still the parent.
  pcntl_waitpid($pid, $status);
  // Additional code handling none zero $status can be added here
}

Я не проверял это, но это хороший стартер

Примечание : Осторожно при использовании разветвления вы можете одновременно запустить слишком много процессов и унести с собой память или сервер.

Реализация максимального параллелизма при параллельной обработке - задача не из легких. Я создал свою собственную библиотеку для обработки параллелизма, в результате чего я потратил сотни часов на то, чтобы она работала, но мне не хватало критически важных функций, поэтому я оказался в tra sh, когда обнаружил процесс пасования / параллельный процесс, в котором реализованы все функции, которые мы требуется

0 голосов
/ 23 апреля 2020

Вы должны использовать асинхронный PHP для достижения этой цели. https://github.com/spatie/async - это библиотека, поддерживающая асинхронность.

use Spatie\Async\Pool;
$pool = Pool::create();

foreach($inputDataGroups as $inputsForTask){
    $json_string_input = json_encode($inputsForTask);
    $filename = 'ImportApp_input_data_'.($group_no + 1).".json";
    file_put_contents($filename,$json_string_input);
    $command = 'php worker.php "' . $filename . '"'.' ImportApp';

    // add to async pool
    $pool->add(function () use ($command){
        exec($command);
    });
    $group_no++;

}
$pool->wait(); // wait pool complets

$dbappList = $this->getImportAppNameByLocationId($LocationID);
return $dbappList;

Я не проверял это. Но я надеюсь, что это направит вас в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...