Skip to content

Instantly share code, notes, and snippets.

@ursuleacv
Created October 17, 2025 15:56
Show Gist options
  • Save ursuleacv/e5f447ae42c87c89473cfceb3c9767a0 to your computer and use it in GitHub Desktop.
Save ursuleacv/e5f447ae42c87c89473cfceb3c9767a0 to your computer and use it in GitHub Desktop.
PHP Parallel Execution with pcntl_fork() and Return Values
<?php
// Make sure the PCNTL extension is available
if (!function_exists('pcntl_fork')) {
die("PCNTL functions not available. Please install the PCNTL extension.\n");
}
// Create a temp directory for process communication
$tempDir = sys_get_temp_dir() . '/pcntl_' . uniqid();
mkdir($tempDir, 0755, true);
// Define three functions that return values instead of echoing
function processData1(): array
{
$startTime = microtime(true);
// Simulate work
sleep(3);
$endTime = microtime(true);
return [
'process' => 'Process 1',
'pid' => getmypid(),
'start_time' => date('H:i:s', (int)$startTime) . substr((string)$startTime, strpos((string)$startTime, '.')),
'end_time' => date('H:i:s', (int)$endTime) . substr((string)$endTime, strpos((string)$endTime, '.')),
'duration' => round($endTime - $startTime, 2) . ' seconds',
'result' => 'Processed 145 customer records'
];
}
function processData2(): array
{
$startTime = microtime(true);
// Simulate work
sleep(2);
$endTime = microtime(true);
return [
'process' => 'Process 2',
'pid' => getmypid(),
'start_time' => date('H:i:s', (int)$startTime) . substr((string)$startTime, strpos((string)$startTime, '.')),
'end_time' => date('H:i:s', (int)$endTime) . substr((string)$endTime, strpos((string)$endTime, '.')),
'duration' => round($endTime - $startTime, 2) . ' seconds',
'result' => 'Generated 57 reports'
];
}
function processData3(): array
{
$startTime = microtime(true);
// Simulate work
sleep(4);
$endTime = microtime(true);
return [
'process' => 'Process 3',
'pid' => getmypid(),
'start_time' => date('H:i:s', (int)$startTime) . substr((string)$startTime, strpos((string)$startTime, '.')),
'end_time' => date('H:i:s', (int)$endTime) . substr((string)$endTime, strpos((string)$endTime, '.')),
'duration' => round($endTime - $startTime, 2) . ' seconds',
'result' => 'Sent 89 notifications'
];
}
$startTime = microtime(true);
// Store child process IDs and output file paths
$childPids = [];
$outputFiles = [];
// Fork for function 1
$outputFile1 = "$tempDir/process_1.json";
$outputFiles[] = $outputFile1;
$pid1 = pcntl_fork();
if ($pid1 == -1) {
// Fork failed
die('Could not fork process 1');
} elseif ($pid1 == 0) {
// Child process
$result = processData1();
file_put_contents($outputFile1, json_encode($result));
exit(0); // Important: child must exit
} else {
// Parent process
echo "Started child process 1 with PID: $pid1" . PHP_EOL;
$childPids[] = $pid1;
}
// Fork for function 2
$outputFile2 = "$tempDir/process_2.json";
$outputFiles[] = $outputFile2;
$pid2 = pcntl_fork();
if ($pid2 == -1) {
// Fork failed
die('Could not fork process 2');
} elseif ($pid2 == 0) {
// Child process
$result = processData2();
file_put_contents($outputFile2, json_encode($result));
exit(0); // Important: child must exit
} else {
// Parent process
echo "Started child process 2 with PID: $pid2" . PHP_EOL;
$childPids[] = $pid2;
}
// Fork for function 3
$outputFile3 = "$tempDir/process_3.json";
$outputFiles[] = $outputFile3;
$pid3 = pcntl_fork();
if ($pid3 == -1) {
// Fork failed
die('Could not fork process 3');
} elseif ($pid3 == 0) {
// Child process
$result = processData3();
file_put_contents($outputFile3, json_encode($result));
exit(0); // Important: child must exit
} else {
// Parent process
echo "Started child process 3 with PID: $pid3" . PHP_EOL;
$childPids[] = $pid3;
}
// Parent process waits for all child processes to complete
foreach ($childPids as $pid) {
pcntl_waitpid($pid, $status);
echo "Child process with PID: $pid has completed with status: $status" . PHP_EOL;
}
$endTime = microtime(true);
echo "All processes have completed!" . PHP_EOL;
echo "------------------------------" . PHP_EOL;
echo "Results from parallel processes:" . PHP_EOL;
echo "------------------------------" . PHP_EOL;
// Collect and display results
$allResults = [];
foreach ($outputFiles as $file) {
if (file_exists($file)) {
$resultJson = file_get_contents($file);
$result = json_decode($resultJson, true);
$allResults[] = $result;
// Clean up temp file
unlink($file);
}
}
// Sort results by process name for consistent display
usort($allResults, function ($a, $b) {
return $a['process'] <=> $b['process'];
});
// Display the results
foreach ($allResults as $result) {
echo "{$result['process']} (PID: {$result['pid']})" . PHP_EOL;
echo " Started at: {$result['start_time']}" . PHP_EOL;
echo " Finished at: {$result['end_time']}" . PHP_EOL;
echo " Duration: {$result['duration']}" . PHP_EOL;
echo " Result: {$result['result']}" . PHP_EOL;
echo "------------------------------" . PHP_EOL;
}
echo "Started: " . date('H:i:s', (int)$startTime) . substr((string)$startTime, strpos((string)$startTime, '.')). PHP_EOL;
echo "Finished: " . date('H:i:s', (int)$endTime) . substr((string)$endTime, strpos((string)$endTime, '.')). PHP_EOL;
echo 'Total duration: ' . round($endTime - $startTime, 2) . ' seconds'. PHP_EOL;
// Clean up temp directory
rmdir($tempDir);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment