澳门新浦京娱乐游戏如何解决PHP无法实现多线程的问题

有未有方法在PHP中落实四线程呢?假诺你正在写二个遵照多台服务器的PHP应用,理想的场合时同偶尔间向多台服务器发送央求,并不是一台接一台。可以兑现吗?当有人想要达成并发成效时,他们常备会想到用fork只怕spawn
threads,可是当他俩开采PHP不支持多线程的时候,大致会改换思路去用一些相当不够好的言语,举例Perl。借令你要建设布局一个劳务来检查正在周转的n台服务器,以明确他们还在正规运维。你恐怕会写上面那样的代码:

$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com"); $timeout = 15; $status = array(); foreach ($hosts as $host) { $errno = 0; $errstr = ""; $s = fsockopen($host, 80, $errno, $errstr, $timeout); if ($s) { $status[$host] = "Connectedn"; fwrite($s, "HEAD / HTTP/1.0rnHost: $hostrnrn"); do { $data = fread($s, 8192); if (strlen($data) == 0) { break; } $status[$host] .= $data; } while (true); fclose($s); } else { $status[$host] = "Connection failed: $errno $errstrn"; } } print_r($status); 

它运维的很好,可是在fsockopen(卡塔尔剖判完hostname并且创设八个得逞的接连在此之前,扩大这段代码来治本多量服务器将消耗很短日子。

故此大家必需放弃这段代码;大家得以成立异步连接-没有须要拭目以俟fsockopen再次回到连接景况。PHP还是供给深入分析hostname,不过将要开发一个连连之后立即回去,进而大家就足以连接下一台服务器。

有两种办法可以兑现;PHP5中能够动用大幅度增涨的stream_socket_client(卡塔尔函数直接沟通掉fsocketopen(卡塔尔(قطر‎。PHP5早前的本子,你供给本人动手,用sockets扩张杀绝难点。上面是PHP第55中学的解决办法:

$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com"); $timeout = 15; $status = array(); $sockets = array(); /* Initiate connections to all the hosts simultaneously */ foreach ($hosts as $id = $host) { $s = stream_socket_client("$host:80", $errno, $errstr, $timeout, STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); if ($s) { $sockets[$id] = $s; $status[$id] = "in progress"; } else { $status[$id] = "failed, $errno $errstr"; } } /* Now, wait for the results to come back in */ while (count($sockets)) { $read = $write = $sockets; /* This is the magic function - explained below */ $n = stream_select($read, $write, $e = null, $timeout); if ($n  0) { /* readable sockets either have data for us, or are failed * connection attempts */ foreach ($read as $r) { $id = array_search($r, $sockets); $data = fread($r, 8192); if (strlen($data) == 0) { if ($status[$id] == "in progress") { $status[$id] = "failed to connect"; } fclose($r); unset($sockets[$id]); } else { $status[$id] .= $data; } } /* writeable sockets can accept an HTTP request */ foreach ($write as $w) { $id = array_search($w, $sockets); fwrite($w, "HEAD / HTTP/1.0rnHost: " . $hosts[$id] . "rnrn"); $status[$id] = "waiting for response"; } } else { /* timed out waiting; assume that all hosts associated * with $sockets are faulty */ foreach ($sockets as $id = $s) { $status[$id] = "timed out " . $status[$id]; } break; } } foreach ($hosts as $id = $host) { echo "Host: $hostn"; echo "Status: " . $status[$id] . "nn"; }  

我们用stream_select(卡塔尔等待sockets展开的连年事件。stream_select(卡塔尔(قطر‎调用系统的select(2卡塔尔函数来专门的学问:前边四个参数是您要运用的streams的数组;你能够对其读取,写入和获得十分。stream_select(卡塔尔(قطر‎可以透过设
置$timeout参数来等待事件发生-事件产生时,相应的sockets数据将写入你传入的参数。

上边是PHP4.1.0之后版本的贯彻,假令你早就在编写翻译PHP时包罗了sockets(ext/socketsState of Qatar匡助,你能够运用根下边相符的代
码,只是要求将上边的streams/filesystem函数的意义用ext/sockets函数完成。重要的例外在于大家用上面包车型地铁函数替代stream_socket_client(卡塔尔来构造建设连接:

// This value is correct for Linux, other systems have other values define('EINPROGRESS', 115); function non_blocking_connect($host, $port, &$errno, &$errstr, $timeout) { $ip = gethostbyname($host); $s = socket_create(AF_INET, SOCK_STREAM, 0); if (socket_set_nonblock($s)) { $r = @socket_connect($s, $ip, $port); if ($r || socket_last_error() == EINPROGRESS) { $errno = EINPROGRESS; return $s; } } $errno = socket_last_error($s); $errstr = socket_strerror($errno); socket_close($s); return false; }  

现在用socket_select()替换掉stream_select(),用socket_read()替换掉fread(),用socket_write()替换掉fwrite(),用socket_close(卡塔尔国替换掉fclose(State of Qatar就足以实施脚本了!PHP5的Red Banner之处在于,你能够用stream_select(卡塔尔(قطر‎处理大约具备的stream。举例你能够由此include
STDIN用它采用键盘输入并保留进数组,你还是能够选拔通过proc_open(卡塔尔展开的管道中的数据。

梦想经过那篇散文,我们能够神奇消逝PHP不能落实三十二线程的难点。

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图