Parallel Processing with PHP: why, how, and when

When we think of PHP, we typically imagine synchronous, single-threaded code that handles one task at a time. But PHP is more versatile than it's often credited for. Thanks to the process control (pcntl) support, PHP can manage parallelism through process forking, a concept native to Unix-like operating systems. Because the process control support is typical on UNIX systems, it works on Unix-like systems like Linux and macOS. What is multiprocessing, and why should you care? Multiprocessing allows you to perform multiple operations at the same time. This is especially useful when: You’re running CPU-intensive tasks that can be parallelized. You need to handle multiple background jobs in parallel. You want to reduce execution time by dividing a task among several processes. You're writing command-line PHP scripts where performance and responsiveness matter. When writing CLI scripts (like a command-line tool), especially for background tasks, daemons, or workers, using pcntl_fork() is a powerful technique. Introducing pcntl_fork(): creating parallel processes in PHP The pcntl_fork() function allows your PHP script to clone itself, creating a child process that runs parallel to the parent. This technique comes straight from the Unix world and opens the door to real multiprocessing in PHP. Here’s a simple example that demonstrates the basic usage of pcntl_fork():

Apr 20, 2025 - 22:19
 0
Parallel Processing with PHP: why, how, and when

When we think of PHP, we typically imagine synchronous, single-threaded code that handles one task at a time.

But PHP is more versatile than it's often credited for. Thanks to the process control (pcntl) support, PHP can manage parallelism through process forking, a concept native to Unix-like operating systems.

Because the process control support is typical on UNIX systems, it works on Unix-like systems like Linux and macOS.

What is multiprocessing, and why should you care?

Multiprocessing allows you to perform multiple operations at the same time. This is especially useful when:

  • You’re running CPU-intensive tasks that can be parallelized.
  • You need to handle multiple background jobs in parallel.
  • You want to reduce execution time by dividing a task among several processes.
  • You're writing command-line PHP scripts where performance and responsiveness matter.

When writing CLI scripts (like a command-line tool), especially for background tasks, daemons, or workers, using pcntl_fork() is a powerful technique.

Introducing pcntl_fork(): creating parallel processes in PHP

The pcntl_fork() function allows your PHP script to clone itself, creating a child process that runs parallel to the parent. This technique comes straight from the Unix world and opens the door to real multiprocessing in PHP.

Here’s a simple example that demonstrates the basic usage of pcntl_fork():



// Fork the process
$pid = pcntl_fork();

if ($pid == -1) {
    // Fork failed
    exit("Could not fork process.\n");
} elseif ($pid > 0) {
    // Parent process
    echo ' Parent process. PID: ' . getmypid() . "\n";
    echo " Created child with PID: $pid\n";

} else {
    // Child process
    echo '  Child process. PID: ' . getmypid() . "\n";
    sleep(1); // Simulate work
    echo "  Child process done.\n";
    exit(0);
}

// Wait for child to exit
pcntl_waitpid($pid, $status);
echo " Child {$pid} has finished with status {$status}.\n";
if (pcntl_wifexited($status)) {
    echo " The child status code represents a normal exit.\n";
    echo ' The child returned the code: ' . pcntl_wexitstatus($status) . "\n";
}
if (pcntl_wifsignaled($status)) {
    echo " The child status exit because a siginal.\n";
    echo ' The child was terminated by signal code: ' . pcntl_wtermsig($status) . "\n";
}

What’s happening here?

  • The script forks itself.
  • Both the parent and child processes continue running independently.
  • The child process executes its logic and exits.
  • The parent process waits for the child to terminate and analyzes the exit status.

This example gives you full control and visibility into how a child process behaves and how the parent can monitor or manage it.

Step-by-step explanation

$pid = pcntl_fork();

The pcntl_fork() function tells the OS: "Create a clone of me to work in parallel.".

After the pctnl_fork, two processes run the same code. One process is the parent process, and the second one is the child process.

If pcntl_fork returns:

  • -1, the clone failed.
  • 0, you’re inside the child process.
  • A positive PID means you’re still the parent, and you just got the child’s ID.
if ($pid == -1) {
    exit("Could not fork process.\n");
}

The forking operation failed. The process exits early.

elseif ($pid > 0) {
    echo ' Parent process. PID: ' . getmypid() . "\n";
    echo " Created child with PID: $pid\n";
}

You’re the parent process.
You print your own PID and the ID of the new child (returned by the fork function).

else {
    echo '  Child process. PID: ' . getmypid() . "\n";
    sleep(1); // Simulate work
    echo "  Child process done.\n";
    exit(0);
}

You’re the child process!
This part is only executed by the child process.
The child sleeps for 1 second (like performing a specific task), prints messages, then exits.

exit(0) is important. It ensures the child doesn’t accidentally run code meant only for the parent.

pcntl_waitpid($pid, $status);

The parent process waits for the child process to finish.
This line tells the parent to pause and wait until the specific child process (by $pid) completes.

echo " Child {$pid} has finished with status {$status}.\n";

Once the child process finishes, the parent process is notified with a status code. We need to inspect the status code to understand why the child terminated the execution (e.g., whether it completed the task correctly, exited with an error, or was interrupted by a signal from the operating system).

if (pcntl_wifexited($status)) {
    echo " The child status code represents a normal exit.\n";
    echo ' The child returned the code: ' . pcntl_wexitstatus($status) . "\n";
}

Check if the child exited normally.
If so, we print the return code (0 if they completed successfully).

if (pcntl_wifsignaled($status)) {
    echo " The child status exit because a signal.\n";
    echo ' The child was terminated by signal code: ' . pcntl_wtermsig($status) . "\n";
}

Or maybe the child was interrupted.
This happens if a signal killed the process (e.g., SIGKILL, SIGTERM).

Code summary

Role Code Block Description
Parent $pid > 0 The parent creates and supervises the task execution.
Child $pid == 0 Child process does the task and exits.
Wait pcntl_waitpid() The parent process waits for the child process to finish.
Status Check pcntl_wifexited(), pcntl_wifsignaled() The parent process checks if the child process finished properly.

When and why to use forking in PHP

You might use pcntl_fork() in CLI scripts when:

  • You want to handle multiple tasks at once, like downloading files, processing queues, or running background jobs.
  • You’re writing a daemon or worker system that needs to scale and manage parallel tasks efficiently.
  • You want to reduce waiting time by handling independent tasks simultaneously.