答え:
同時実行機能を実装したいとき、通常は fork や spawn
スレッドの使用を考えますが、PHP がマルチスレッドをサポートしていないことがわかると、気が変わり、次のような十分ではない言語を使用する可能性があります。パールとして。
実際、ほとんどの場合、フォークやスレッドを使用する必要はなく、フォークやスレッドを使用するよりもパフォーマンスが向上します。
実行中のサーバーがまだ正常に機能していることを確認するサービスを構築するとします。次のようなコードを書くとよいでしょう:
コードをコピーします コードは次のとおりです:
$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com" ");
$timeout = 15; $status = array();
foreach ($hosts として $host) {
$errno = 0;
$errstr = "";
$s = fsockopen($host, 80, $errno, $ errstr, $timeout);
if ($s) {
$status[$host] = "接続済み";
fwrite($s, "HEAD / HTTP/1.0rnHost: $hostrnrn"); {
$data = fread($s, 8192);
if (strlen($data) == 0) { ブレーク; }
$status[$host] .= $data; while (true); $s);
} else {
$status[$host] = "接続に失敗しました: $errno $errstrn";
print_r($status);
正常に動作しますが、このコードを拡張して多数のサーバーを管理するには、 fsockopen() がホスト名を解析して正常な接続を確立するまで (または $timeout 秒遅れて) 長い時間がかかります。
したがって、このコードを放棄する必要があります。fsockopen が接続ステータスを返すのを待つ必要がなく、非同期接続を確立できます。 PHP は依然としてホスト名を解決する必要があります (したがって、IP を直接使用する方が賢明です) が、接続を開いた後すぐにホスト名が返されるため、次のサーバーに接続できます。
これを実現するには 2 つの方法があります。PHP5 では、新しい stream_socket_client() 関数を使用して fsocketopen() を直接置き換えることができます。 PHP5 より前のバージョンの場合、問題を解決するには自分で実行し、ソケット拡張機能を使用する必要があります。
PHP5 での解決策は次のとおりです:
コードをコピーします
コードは次のとおりです:
$hosts = array("host1.sample.com", "host2.sample.com", "host3.sample.com" "); $timeout = 15; $status = array(); $sockets = array(); 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] = "進行中";
} else {
$ status[$id] = "失敗しました、$errno $errstr";
}
}
while (count($sockets)) {
$read = $write = $sockets; read, $write , $e = null, $timeout);
if ($n > 0) {
foreach ($read as $r) {
$id = array_search($r, $sockets); = fread($ r, 8192);
if (strlen($data) == 0) {
if ($status[$id] == "進行中") {
$status[$id] = "失敗しましたconnect";
}
fclose($r);
unset($sockets[$id]);
} else {
$status[$id] .= $data;
}
}
foreach ($write as $ w) {
$id = array_search($w, $sockets);
fwrite($w, "HEAD / HTTP/1.0rnHost: " . $hosts[$id] . "rnrn"); ] = "応答を待っています";
}
} else {
foreach ($sockets as $id => $s) {
$status[$id] = "タイムアウト"
}
break;
}
}
foreach ($hosts as $id => $host) {
echo "ステータス: " $status[$id]
; }
?> ;
stream_select() を使用して、ソケットが開く接続イベントを待ちます。 stream_select() は、システムの select(2) 関数を呼び出して機能します。最初の 3 つのパラメータは、使用するストリームの配列であり、(3 つのパラメータごとに) 読み取り、書き込み、例外の取得が可能です。 stream_select() は、$timeout (秒) パラメーターを設定することでイベントが発生するのを待つことができます。イベントが発生すると、渡したパラメーターに対応するソケット データが書き込まれます。
以下は PHP 4.1.0 以降の実装です。PHP のコンパイル時にソケット (ext/sockets) サポートを組み込んでいる場合は、上記と同様のコードを使用できますが、ストリーム/ファイルシステムの関数には ext を使用する必要があります。上記の /sockets 関数の実装。主な違いは、
stream_socket_client() の代わりに次の関数を使用して接続を確立することです。
コードをコピーします
コードは次のとおりです:
// この値は Linux では正しいですが、他のシステムには他の値があります
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) , $ ポート);
if ($r || ソケット_last_error() == EINPROGRESS;
$errno = EINPROGRESS;
$errno = ソケット_last_error($s); $errno );
socket_close($s);
戻り値
?>
ここで、stream_select()をsocket_select()に、fread()をsocket_read()に、fwrite()を
socket_write()に、fclose()をsocket_close()に置き換えると、スクリプトを実行できるようになります。
PHP5 の進歩は、stream_select() を使用してほぼすべてのストリームを処理できることです。たとえば、これを使用して、インクルード STDIN を介してキーボード入力を受信し、それを配列に保存できます。また、開いたパイプからデータを受信することもできます。 proc_open() データを通じて。
PHP4.3.x自体にストリーム処理機能を持たせたい場合は、fsockopenを非同期で動作させるパッチを用意しました。このパッチは非推奨であり、正式にリリースされた PHP バージョンには含まれません。このパッチには stream_socket_client() 関数の実装が含まれており、これを使用してスクリプトを
PHP5 と互換性を持たせることができます。
http://www.bkjia.com/PHPjc/718626.html
www.bkjia.com
truehttp://www.bkjia.com/PHPjc/718626.html技術記事回答: 同時実行機能を実装したいとき、通常はフォークまたは生成スレッドの使用を考えますが、PHP がマルチスレッドをサポートしていないことがわかると、気が変わって次のメソッドを使用する可能性があります...