Created
October 17, 2025 15:56
-
-
Save ursuleacv/e5f447ae42c87c89473cfceb3c9767a0 to your computer and use it in GitHub Desktop.
PHP Parallel Execution with pcntl_fork() and Return Values
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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