Current Location: Home> Latest Articles> The risks and responses of socket_set_block in high concurrency environments

The risks and responses of socket_set_block in high concurrency environments

gitbox 2025-05-26

1. The working principle of socket_set_block and high concurrency risk

socket_set_block After socket is set to blocking mode, IO operations (such as socket_read , socket_write ) will block the current process or thread until the data read is completed or the write is successful. This is very simple and effective in single-threaded or low-concurrency scenarios, but in high-concurrency scenarios, the risks are mainly reflected in the following points:

  1. Blockage causes resource occupation <br> The blocking mode will make the program that handles a request unable to continue execution for a moment, especially when the network is delayed or the peer responds slowly, the process will "stuck" in the IO stage, causing a large number of processes to wait and resources to be occupied.

  2. Decreased throughput, increased response latency <br> When a large number of connections are blocked, the server cannot process new connection requests in time, resulting in a longer response time and a worse user experience.

  3. The number of threads/processes is limited <br> The concurrency capability of the server is limited by the number of available threads or processes. Blocking operations make these threads or processes in a waiting state, which is very easy to cause the thread pool to be exhausted.

  4. Deadlock risk <br> If competition for mutually exclusive resources is involved during blocking and waiting, it is easy to cause deadlocks and cause program stuck.


2. Common coping strategies in high concurrency environments

1. Use the non-blocking mode socket_set_nonblock

By calling socket_set_nonblock to set socket to non-blocking mode, IO operations will not block the current process, but will return immediately. Combined with event-driven mechanisms (such as select , poll , or libevent in PHP extensions) can effectively improve concurrent processing capabilities.

 <?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_bind($socket, '0.0.0.0', 8080);
socket_listen($socket);

socket_set_nonblock($socket);

while (true) {
    $client = @socket_accept($socket);
    if ($client === false) {
        // No new connection,Continue the loop
        usleep(10000); // Have a break,reduceCPUOccupancy
        continue;
    }

    // To the client socket Also set non-blocking
    socket_set_nonblock($client);

    // When reading or writing data,Combined socket_select Listening status
}
?>

2. Use socket_select to achieve multiplexing

socket_select can listen to the read and write status of multiple sockets, avoid blocking a single connection, and improve the efficiency of the server to process multiple connections.

 <?php
$read = [$socket];
$write = null;
$except = null;

if (socket_select($read, $write, $except, 0, 200000)) {
    foreach ($read as $readSocket) {
        if ($readSocket === $socket) {
            $client = socket_accept($socket);
            socket_set_nonblock($client);
            // Add to Listen
        } else {
            $data = socket_read($readSocket, 1024);
            if ($data === false || $data === '') {
                socket_close($readSocket);
                // Remove from the List of List
            } else {
                // Processing data
            }
        }
    }
}
?>

3. Use asynchronous IO or event-driven framework

With the help of asynchronous frameworks such as Swoole and ReactPHP, blocking can be completely avoided, and a large number of concurrent connections can be processed asynchronously, greatly improving performance.

 <?php
use Swoole\Coroutine\Http\Server;

$server = new Server("0.0.0.0", 9501);

$server->handle('/', function ($request, $response) {
    $response->end("Hello, Swoole!");
});

$server->start();
?>

4. Thread or process pooling technology

Use multi-process or multi-threading reasonably to assign blocking operations to independent worker threads or processes to avoid blocking of the main thread.


3. Summary

Risk points Response measures
Blocking causes the process to wait for resource usage Use non-blocking mode or event driver
Response latency and throughput drop Use socket_select to listen for multiple connections
Thread pool exhausted Use multi-threaded/multi-process pools to share stress
Deadlock risk Design a reasonable resource access strategy to avoid mutually exclusive deadlocks

In a high concurrency environment, try to avoid using blocking sockets and make rational use of non-blocking, event-driven models and asynchronous frameworks to ensure the efficient and stable operation of PHP programs.