fsockopen阻塞和非阻塞

异步/同步(被调用者),阻塞/非阻塞(调用者)

  • 数据流的阻塞和非阻塞装填
  • $flag 取值为0或1 0是非阻塞,1是阻塞
  • stream_set_blocking ($resource, $flag);
阻塞的意义是什么呢?

某个函数读取一个网络流,当没有未读取字节的时候,程序该怎么办?是一直等待,直到下一个未读取的字节的出现,还是立即告诉调用者当前没有新内容?前者是阻塞的,后者是非阻塞的。

阻塞的好处是,排除其它非正常因素,阻塞的是按顺序执行的同步的读取。

而非阻塞,因为不必等待内容,所以能异步的执行,现在读到读不到都没关系,执行读取操作后立刻就继续往下做别的事情。

    function asyncRequest(string $url, array $param = [])
    {
        $url_info = parse_url($url);
        $host = $url_info['host'];
        $path = $url_info['path'];
        $query = isset($param) ? http_build_query($param) : '';
        $port = 80;
        $errno = 0;
        $errstr = '';
        $timeout = 30; //连接超时时间(S)

        $fp = @fsockopen($host, $port, $errno, $errstr, $timeout);
        //$fp = stream_socket_client("tcp://".$host.":".$port, $errno, $errstr, $timeout);

        if (!$fp) {
            logs('连接失败', 'async_request_logs');
            return '连接失败';
        }

        if ($errno || !$fp) {
            logs($errstr, 'async_request_logs');
            return $errstr;
        }

        stream_set_blocking($fp, 0); //非阻塞
        stream_set_timeout($fp, 3);//响应超时时间(S)
        $out = "POST " . $path . " HTTP/1.1\r\n";
        $out .= "host:" . $host . "\r\n";
        $out .= "content-length:" . strlen($query) . "\r\n";
        $out .= "content-type:application/x-www-form-urlencoded\r\n";
        $out .= "connection:close\r\n\r\n";
        $out .= $query;

        $result = @fputs($fp, $out);
        usleep(1000); // 延迟1毫秒,如果没有这延时,可能在nginx服务器上就无法执行成功
        @fclose($fp);
        return $result;
    }

同步异步,阻塞非阻塞他们针对的对象是不一样的。对于调用者来说是阻塞跟非阻塞,被调用者是同步跟异步。

同步:A调用B,此时只有等B有结果了才返回。

异步: A调用B,B立即返回,无须等待。当B处理完之后会通过通知或者回调函数的方式来告诉A结果。

阻塞:A调用B,A会被被挂起,一直在等待B的结果,什么事都不能干。

非阻塞:A调用B,自己用被挂起等待B的结果,可以去干其他的事情。

zed
请先登录后发表评论
  • latest comments
  • 总共0条评论