Mastering PHP Concurrency: From Fork Processes to Swoole’s Async IO

This article explains the evolution of concurrent I/O in PHP—from traditional multi‑process and multi‑thread blocking models, through the leader‑follower pattern and I/O multiplexing with epoll, to modern asynchronous programming using the Reactor model, coroutines, and the high‑performance Swoole extension.

21CTO
21CTO
21CTO
Mastering PHP Concurrency: From Fork Processes to Swoole’s Async IO
Concurrent I/O has always been a technical challenge in backend programming, evolving from synchronous blocking fork processes to multi‑process/multi‑thread models, and now to asynchronous I/O and coroutines. PHP developers, accustomed to the LAMP stack, often lack low‑level knowledge; this article introduces various PHP concurrency approaches and details Swoole usage.

Multi‑Process / Multi‑Thread Sync Blocking

Early server programs used a process per client: accept a connection, fork a child process, and handle communication synchronously. Threads later appeared as lighter‑weight alternatives sharing memory, simplifying interaction but requiring IPC mechanisms for processes.

Create a socket, bind, and listen (e.g., stream_socket_server or PHP sockets extension).

Enter a while loop, blocking on accept for new client connections.

In the parent, fork ( pcntl_fork) or create a thread ( new Thread) for each client.

Child processes/threads block on fread to receive data, process it, then send a response with fwrite.

When a client disconnects, the child exits and the parent reaps it.

This model incurs high overhead for creating and destroying processes/threads, limiting scalability for busy servers.

Leader‑Follower Model

At startup, N processes are created. Each waits on accept. When a client connects, one process handles the request while others continue accepting new connections. The model reuses processes without extra creation cost, offering high performance; it powers servers like Apache and PHP‑FPM.

IO Multiplexing / Event Loop / Async Non‑Blocking

Linux provided select (1024 connections) and later poll, but both required scanning all descriptors, wasting CPU. The epoll system call (Linux 2.6) supports unlimited connections without polling, solving the C10K problem. High‑concurrency servers such as Nginx, Node.js, Erlang, and Golang rely on epoll.

Reactor Model

The Reactor monitors socket events and dispatches callbacks. Core operations:

add : register a socket (listen, client, pipe, eventfd, signal) with the reactor.

set : modify event types (readable, writable). Writable events are needed when the OS buffer is full and send returns EAGAIN.

del : remove a socket from monitoring.

callback : user‑defined logic executed when events occur (implemented via function pointers in C, closures in PHP, etc.).

Reactor can be combined with multi‑process or multi‑thread architectures to achieve asynchronous non‑blocking I/O while utilizing multiple CPU cores.

Coroutines

Coroutines are built on the asynchronous Reactor model but provide sequential‑style code while executing non‑blocking operations under the hood. Tencent’s TSF (Tencent Server Framework) implements coroutine‑like behavior in PHP using generators.

PHP Extensions for Concurrency

Stream – socket wrapper in the PHP core.

Sockets – low‑level socket API.

Libevent – wrapper for libevent library.

Event – higher‑level libevent wrapper with OO interface, timers, and signal handling.

Pcntl/Posix – process, signal, and process‑management support.

Pthread – thread, lock, and synchronization support.

Shared memory, semaphores, message queues – IPC extensions.

PECL – repository of additional extensions for system, data analysis, algorithms, scientific computing, graphics, etc.

Swoole Extension

Swoole combines a multi‑thread Reactor with multi‑process workers, offering full async and semi‑sync modes. It provides high‑performance networking, efficient connection handling, and supports asynchronous tasks, timers, MySQL/Redis clients, and WebSocket servers.

Accept thread to eliminate accept bottleneck.

Multiple I/O threads for better CPU utilization.

Full async and half‑sync/half‑async modes.

Asynchronous I/O for high‑concurrency handling.

Synchronous mode for complex business logic.

Built‑in support for connection traversal, data merging/splitting, and atomic sends.

Server and Client Examples

Typical asynchronous TCP server creation:

$server = new swoole_server("0.0.0.0", 9501);
$server->on('Connect', function ($serv, $fd) { /* ... */ });
$server->on('Receive', function ($serv, $fd, $tid, $data) { /* ... */ });
$server->on('Close', function ($serv, $fd) { /* ... */ });
$server->start();

Clients can be asynchronous (with callbacks) or synchronous (blocking). Asynchronous tasks run in a process pool, useful for heavy or blocking operations such as broadcasting in IM or file I/O.

Async Timers

Swoole provides tick and after functions similar to JavaScript’s setInterval and setTimeout, executing callbacks at specified millisecond intervals.

Async MySQL and Redis Clients

Swoole includes non‑blocking MySQL and Redis clients, with optional connection pooling to reuse connections and avoid resource exhaustion.

Async Web and WebSocket

Built‑in WebSocket server enables push‑based applications such as WebIM. Example projects are available on GitHub.

TSF Coroutine Example

TSF allows writing sequential‑style code that runs asynchronously. Example (simplified):

$client = new swoole_http_client('example.com', 80);
$client->set(['timeout' => -1]);
$client->get('/path', function ($cli) {
    echo $cli->body;
});

Running PHP + Swoole on Raspberry Pi

Both PHP and Swoole can be compiled for ARM, enabling development of network programs on Raspberry Pi devices.

Performance comparison
Performance comparison

Overall, leveraging Swoole transforms PHP from a traditional blocking language into a powerful platform for high‑performance, concurrent network services.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

concurrencyReactorcoroutinebackend-developmentAsync IO
21CTO
Written by

21CTO

21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.