How to Write a Multi-Threaded Script in PHP?


Generally, most of the programs written in PHP are single-threaded, but the web-servers usually spawn a new thread each time there's a new request. So when you run a PHP script, it runs a single threaded program, but when used in conjunction with a web-server, the web-server will spawn a new thread for each incoming request.

Despite being most of the scripts being single threaded in nature, it's possible to create a multi-threaded PHP script.

Parallel processing in PHP can be achieved by pcntl_fork(). While it is not technically multi-threaded, it creates a child process of the parent running script.

It can be used to distribute workload, parallel process. It's highly useful when you're dealing with a large dataset or anything that could benefit by having multiple processes instead of one.

However, it's important to note that this process also inherits the resources from its parent process - this means that your Redis, MySQL connections or file descriptors, etc. are also inherited by the children processes. If two or more children processes access the connection at the same time, it would cause the children process to have race conditions, crashes and more.

To avoid the side-effects, I recommend that write your script in such a way that each child process creates its own required resources such as a MySQL connection.

For example, the function below contains the code that the children process would run.

<?php

    function createAChildProcess() {

        echo mt_rand() . PHP_EOL;

    }

?>
        
The piece of code below forks the parent 8 times (i.e., creates 8 concurrent PHP processes), waits for them to finish their work and then eventually the parent process also exits.

<?php

$processes = 8;

for($x = 0; $x < $processes; $x++) {

    $pid = pcntl_fork();

    if ($pid == -1) {
        exit("Error forking...");
    } else {
        if ($pid == 0) {
            createAChildProcess();
            exit();
        }
    }

}

while (pcntl_waitpid(0, $status) != -1) {
    // Waiting
}

echo "All tasks have been completed.";

?>
        
With that being said, you should be able to achieve parallel processing with PHP. Always make sure that the children processes create their own resources so that you don't have problems with children processes trying to use the same resource at the same time.