霜天部落 | 关注LAMP高性能、高并发架构的设计与研究

如何理解stream_set_blocking的阻塞和非阻塞

伪代码如下:

<?php
$main_socket = stream_socket_server("tcp://0.0.0.0:8888", $error_code, $error_msg)  or die('create server failed');

while(1)
{
    set_error_handler(function(){}); 
    $new_socket = stream_socket_accept($main_socket, 5, $remote_address);
    restore_error_handler();

    if(!$new_socket) continue;

    //屏蔽或开启本行代码进行调试
    //stream_set_blocking($new_socket, 0);

    if(pcntl_fork() == 0)
    {
        while(1)
        {
            $pid = posix_getpid();
            $request = fread($new_socket, 8192);
            var_dump($request);
            $msg = trim($request);
            if(!empty($msg))
            {
                $response = "{$pid} | {$remote_address} | {$msg}" . PHP_EOL;
                fwrite($new_socket, $response);
            }
        }
        exit(0);
    }
}

区别就在于: 
1、当 socket处于阻塞模式时,比如:fread系统调用必须等待socket有数据返回,即进程因系统调用阻塞;相反若处于非阻塞模式,内核不管socket数据有没有准备好,都会立即返回给进程。

2、另外进程阻塞和socket阻塞不是一个概念,进程阻塞是因为系统调用所致,socket是否阻塞只是说明socket上事件是不是可以内核即刻处理。