<?php
declare(strict_types = 1);
function execute_task(int $task_id): void
{
echo 'Starting task: ' . $task_id . PHP_EOL;
$execution_time = rand(5, 10);
sleep($execution_time);
echo "Completed task: ${task_id}. Took ${execution_time} seconds.\n";
}
function generator(): Generator
{
$item_count = 50;
for ($i = 1; $i <= $item_count; $i++) {
yield $i;
}
}
function launch(): void
{
$processCount = 0;
$status = null;
echo 'Running as pid: ' . getmypid() . PHP_EOL;
$taskList = generator();
do {
echo 'Still tasks to do' . PHP_EOL;
if ($processCount >= 5) {
echo 'Waiting, currently running: ' . $processCount . PHP_EOL;
pcntl_wait($status);
$processCount--;
continue;
}
echo 'Tasks running: ' . $processCount . PHP_EOL;
$task = $taskList->current();
$taskList->next();
$processCount++;
$pid = pcntl_fork();
if ($pid === -1) {
exit('Error forking...' . PHP_EOL);
}
if ($pid === 0) {
$processList[] = getmypid();
echo 'Running task as pid: ' . getmypid() . PHP_EOL;
execute_task($task);
exit();
}
} while ($taskList->valid());
$waitForChildrenToFinish = true;
while ($waitForChildrenToFinish) {
if (pcntl_waitpid(0, $status) === -1) {
echo 'parallel execution is complete' . PHP_EOL;
$waitForChildrenToFinish = false;
}
}
}
launch();