How to use Multithreading in php

Multithreading is a powerful technology that allows a program to run many threads concurrently, enhancing speed by efficiently using multiple CPU cores. While PHP is not well recognised for its multithreading capabilities, there are extensions and frameworks that may be used to achieve multithreading in PHP
 In this article, you’ll learn how to implement multithreading in PHP, step by step.

What is Multithreading?

Multithreading is a concurrency method used in computer programming and software development that allows a program to run numerous threads of code at the same time within a single process. A thread is the smallest unit of execution inside a process, and it may be perceived as a separate or independent flow of control.

How to use Multithreading in PHP?

If you want to use multithreading in php, follow the following steps:

Step 1: Checking the presence of pthreads extensions

In this step, we prepare our environment by ensuring that the essential extensions for multithreading in PHP are installed and available. We mainly check for the presence of the 'pthreads' extension. To check the presence of 'pthreads' extension, the code is as followed:

if (extension_loaded('pthreads')) {
    echo "The pthreads extension is loaded.\n";
} else {
    echo "The pthreads extension is not loaded.\n";
    exit(1);
}
  • We use 'extension_loaded('pthreads')' to check if the 'pthreads' extension is loaded. If it’s loaded, it means that multithreading support is available.
  • If the extension is not loaded, we print an error message and exit the script with a status code of 1.

If you don’t have 'pthreads' extension and an error message occurs just like below then you can follow following steps to load your 'pthreads' extension.
Error message:

  1. Download the latest 'pthread' extension using the following link:
    http://windows.php.net/downloads/pecl/releases/pthreads/
  2. Copy and paste the “pthreadsVC2.dll” file in the “php” folder that is located inside your “xampp” folder.
  3. Copy and paste the “pthreads.dll” file in the “ext” folder that lies inside the “php” folder.
  4. Open your “php.ini” file and type the command “extension=php_pthreads.dll”.
  5. Save your “php.ini” file.

Now you are ready to use your 'pthreads' extension.

Step 2:  Using pthread extensions

In this step, we introduce the basics of multithreading in PHP using the pthreads extension. We create a custom thread class, spawn multiple threads, and execute them concurrently. The code is as followed:

// Define a custom thread classclass MyThread extends Thread {
    public function run() {
        echo "Thread ID: " . $this->getThreadId() . " is running.\n";
    }
}
$threads = [];
$thread_Count = 5;
// Create and start multiple threads
for ($i = 0; $i < $thread_Count; $i++) {
    $threads[$i] = new MyThread();
    $threads[$i]->start();
}
// Wait for all threads to finish
foreach ($threads as $thread) {
    $thread->join();
}
  • We define a new thread class called 'MyThread' , which extends the 'Thread' class provided by the 'pthreads' extension. The 'run' method defines the code that will be performed within each thread.
  • We create an array '$threads' to store instances of our custom thread class.
  • We create 'MyThread'instances within a loop, start them with the 'start()' function, and put them in the '$threads' array.
  • Another loop uses the 'join()' technique to wait for each thread to finish. This ensures that all threads have completed before proceeding.
Tip: Optimize workload distribution for better performance in multithreaded PHP apps.

Step 3: Synchronization with mutexes

We handle the issue of potential race situations when multiple threads access shared resources in this phase. To secure shared data from concurrent access, we employ synchronization mechanisms such as mutexes. The code is as shown:

// Define a class with a shared resource and a mutex
class SharedResource {
    private $mutex;
    private $data;
    public function __construct() {
        $this->mutex = new Mutex();
        $this->data = [];
    }
    public function addToData($value) {
        $this->mutex->lock(); // Acquiring the mutex lock
        $this->data[] = $value;
        $this->mutex->unlock(); // Releasing the mutex lock
    }
    public function getData() {
        return $this->data;
    }
}
 // Now Define a custom thread class
 class MyThread extends Thread {
    private $shared_Resource;
    private $value;
    public function __construct($shared_Resource, $value) {
        $this->shared_Resource = $shared_Resource;
        $this->value = $value;
    }
    public function run() {
        $this->shared_Resource->addToData($this->value);
    }
}
$shared_Resource = new SharedResource();
$threads = [];
$thread_Count = 5;
// Create and start multiple threads
for ($i = 0; $i < $thread_Count; $i++) {
    $threads[$i] = new MyThread($shared_Resource, $i);
    $threads[$i]->start();
}
// Wait for all threads to finish
foreach ($threads as $thread) {
    $thread->join();
}
$data = $shared_Resource->getData();
print_r($data);
  1. First, we will define a 'SharedResource' class that contains a private mutex ('$mutex') and an array ('$data') to store shared data.
  2. To ensure exclusive access, the 'addToData' function of 'SharedResource' locks the mutex before adding a value to the shared data array and unlocks it afterwards.
  3. Each 'MyThread' instance is given access to the shared resource in its constructor. In the 'run' method, each thread adds a value to the shared data using the 'addToData' method.
  4. After creating and starting the threads, we wait for them to finish using the 'join()' method.
  5. Finally, we get and print data from a shared resource, demonstrating synchronized access to shared data.
Caution: Beware of race conditions and synchronization issues when implementing multithreading in PHP.

Some Alternative Approaches

We can also use an alternative method that is 'pcntl' extension which helps us in achieving parallelism in php. Parallelism in PHP refers to the execution of multiple tasks or processes simultaneously.

A. Using 'pcntl' extension

The 'pcntl' PHP extension provides process control capabilities, enabling you to create and manage child processes. While it does not support multithreading, it may create parallelism by running distinct processes concurrently. 

<?php<br>
$processing = [];
$process_Count = 5;
for ($i = 0; $i < $process_Count; $i++) {
    $pid = pcntl_fork();    
    if ($pid == -1) {
        die("Failed to fork.\n");
    } elseif ($pid == 0) {
        // Child process
        echo "Child process with PID " . getmypid() . " is running.\n";
        sleep(2); // Simulate some work
        exit(0);
    } else {
        $processing[] = $pid;
    }
}
foreach ($processing as $pid) {
    pcntl_waitpid($pid, $status);
}
?>
  • An empty array  '$processing' is created to store child process IDs (PIDs), and '$process_Count' is set to ‘5’ to specify the number of child processes to create.
  • A loop is used to create child processes. Inside the loop:
    • 'pcntl_fork()' is called to create a new child process.
    • If the fork fails ('$pid == -1'), the script exits with an error message.
    • In the child process ('$pid == 0'):
      • It prints a message with its PID.
      • Simulates work by sleeping for ‘2’ seconds.
      • Exits the child process.
  • After creating all child processes, the parent process loops over the '$processing' array, calling 'pcntl_waitpid()' to wait for each child process to finish. This assures that the parent process does not complete execution until all child processes have completed.

While 'pcntl' enables parallelism in PHP via process management, it’s important to remember that processes are more isolated than threads, making communication between them more difficult. Depending on your application’s needs, you should choose between 'pthreads' and 'pcntl'.