首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP多線程實現兩大方案:stream_socket_client異步IO與fsockopen模擬並發

     編輯:PHP 綜合知識

背景

PHP 單線程模型,但可通過異步 IO 或進程分離實現並發效果。

方案一:PHP 5+ stream_socket_client 異步非阻塞

$hosts = array("host1", "host2", "host3");
$timeout = 15;
$sockets = array();

// 並發發起連接
foreach ($hosts as $id => $host) {
    $s = stream_socket_client("tcp://$host:80", $errno, $errstr, $timeout,
        STREAM_CLIENT_ASYNC_CONNECT | STREAM_CLIENT_CONNECT);
    if ($s) { $sockets[$id] = $s; $status[$id] = "in progress"; }
}

// 使用 stream_select 監聽就緒流
while (count($sockets)) {
    $read = $write = $sockets;
    $n = stream_select($read, $write, $e=null, $timeout);
    if ($n > 0) {
        foreach ($read as $r) {
            $id = array_search($r, $sockets);
            $data = fread($r, 8192);
            if (strlen($data)==0) { fclose($r); unset($sockets[$id]); }
            else { $status[$id] .= $data; }
        }
        foreach ($write as $w) {
            $id = array_search($w, $sockets);
            fwrite($w, "HEAD / HTTP/1.0\r\nHost: {$hosts[$id]}\r\n\r\n");
            $status[$id] = "waiting response";
        }
    }
}

方案二:fsockopen + HTTP 分離請求模擬多線程

class Thread {
    var $hooks=array(), $args=array();
    function addThread($func) {
        $this->hooks[] = $func;
        $this->args[] = array_slice(func_get_args(), 1);
    }
    function runThread() {
        if (isset($_GET['flag'])) {
            call_user_func_array($this->hooks[$_GET['flag']], $this->args[$_GET['flag']]);
        } else {
            foreach ($this->hooks as $i=>$func) {
                $fp = fsockopen($_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT']);
                fputs($fp, "GET {$_SERVER['PHP_SELF']}?flag=$i HTTP/1.1\r\nHost: {$_SERVER['HTTP_HOST']}\r\nConnection: Close\r\n\r\n");
                fclose($fp); // 非阻塞發起子請求
            }
        }
    }
}
// 使用:
$t = new Thread();
$t->addThread('func1', $arg1);
$t->addThread('func2', $arg2);
$t->runThread();

對比總結

方案優點缺點
stream_socket_client真異步IO、單進程高併發、PHP5.3+原生代碼較複雜、需理解流選擇機制
fsockopen分離請求思路簡單、兼容舊版本、易理解實際開啟多進程、資源消耗大、受服務器並發限制
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved