Concurrency and Multithreading in PHP: From Theory to Practice

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Concurrency and Multithreading in PHP: Modern Approaches



PHP is traditionally associated with synchronous code execution. However, modern web applications require handling multiple tasks simultaneously: from file uploads to parsing large data. In this article, we will explore how to implement concurrency and multithreading in PHP using built-in and third-party tools.



What are Concurrency and Multithreading?



Concurrency is the ability of a program to execute multiple tasks "simultaneously" by switching between them. Multithreading is a special case of concurrency where tasks are executed in separate operating system threads.



In PHP prior to version 7.4, there was no native support for threads. However, with the introduction of pthreads and parallel extensions, as well as improved process handling, the situation has changed.



1. Multithreading with the parallel Extension



The parallel extension is a modern way to work with threads in PHP 7.4+. It uses shared memory, allowing efficient data exchange between threads.



Installation:

pecl install parallel


Example of creating a thread:

<?phpuse parallel\\Runtime;

$runtime = new Runtime();$future = $runtime->run(function() { // Heavy computations $result = 0; for ($i = 0; $i < 1000000; $i++) { $result += sqrt($i); } return $result;});

echo "Main thread continues working...";$result = $future->value(); // Get the resultecho "Result: $result";?>


Advantages of parallel:

  • Native thread support without extra dependencies
  • Shared memory between threads
  • Ability to pass closures and objects


Disadvantages:

  • Requires PHP 7.4+ and ZTS (Zend Thread Safety)
  • Not supported on Windows
  • Debugging difficulties


2. Asynchrony through Processes: pcntl_fork



If you don't need shared memory, you can use processes with pcntl_fork(). This is a classic Unix approach.



<?php$pid = pcntl_fork();

if ($pid == -1) { die("Error creating process");} elseif ($pid) { // Parent process echo "Parent: waiting for child process..."; pcntl_wait($status); echo "Parent: child process completed";} else { // Child process echo "Child: executing task..."; sleep(3); exit(0);}?>


Features of working with processes:

  • Each process has its own memory
  • Use sockets, shared memory (shmop), or files for data exchange
  • Zombie processes must be handled via pcntl_wait()


3. Concurrency through Asynchronous Functions and ReactPHP



For I/O tasks (network requests, file reading), it is more efficient to use asynchronous libraries such as ReactPHP or Amp. They do not create threads but allow concurrent task execution through an event loop.



Example with ReactPHP:

<?phprequire 'vendor/autoload.php';

use React\\EventLoop\\Factory;use React\\Http\\Browser;

$loop = Factory::create();$client = new Browser($loop);

$promises = [];$urls = [ 'https://api.example.com/data1', 'https://api.example.com/data2', 'https://api.example.com/data3'];

foreach ($urls as $url) { $promises[] = $client->get($url);}

// Wait for all requests in parallel$results = [];foreach ($promises as $promise) { $results[] = $promise->wait();}

$loop->run();print_r($results);?>

Blogs

Book Recommendations