PHP スレッドの同時実行の種類について詳しく説明_PHP チュートリアル

WBOY
リリース: 2016-07-15 13:28:11
オリジナル
1038 人が閲覧しました

プロジェクトを実行するときに最初に考慮するのはスレッドです。PHP でスレッドを実装する方法をここで見てみましょう。多くの PHP 開発者は、標準の PHP にはスレッド機能がないため、実際の PHP アプリケーションではマルチタスクは不可能であると考えています。

たとえば、アプリケーションが別の Web サイトからの情報を必要とする場合、リモートの取得が完了するまでアプリケーションを停止する必要があります。これは間違っています!この記事では、stream_select と stream_socket_client を使用してインプロセス PHP マルチタスクを実装する方法を学びます。 PHP はスレッドをサポートしていません。それにもかかわらず、ほとんどの PHP 開発者が上記で信じていることに反して、PHP アプリケーションはマルチタスクを実行できます。まずは、PHP プログラミングにおける「マルチタスク」と「スレッド化」が何を意味するのかをできるだけ明確に説明しましょう。

PHP スレッド同時実行の種類

まず最初に、トピックとは無関係ないくつかの例を脇に置いておきましょう。 PHP とマルチタスクまたは同時実行性との関係は複雑です。大まかに言うと、PHP にはマルチタスクが含まれることがよくあります。これは、標準のサーバー側 PHP インストール (Apache モジュールなど) を使用したマルチタスク方式です。言い換えれば、複数のクライアント (Web ブラウザ) が、PHP で解釈された同じページを同時に要求することができ、Web サーバーはそれらすべてをほぼ同時に返します。

ある Web ページが他の Web ページの配信をブロックすることはありませんが、サーバーのメモリやネットワーク帯域幅などのリソースが限られているため、相互にわずかにブロックする可能性があります。したがって、同時実行性を達成するためのシステムレベルの要件は、PHP ベースのソリューションに適している可能性があります。実装に関しては、PHP を使用すると、管理 Web サーバーが同時実行性の実装を担当できます。

近年、Ajax という名前でのクライアント側の同時実行性も開発者の注目を集めています。 Ajax の意味はかなり曖昧になってきましたが、その 1 つの側面は、ブラウザーの表示で計算を実行し、メニュー項目の選択などのユーザーのアクションに対する応答を保持できることです。これは実際にはある種のマルチタスクです。 PHP でコーディングされた Ajax は単なる Ajax ですが、特定の PHP は必要ありません。他の言語の Ajax フレームワークはすべてまったく同じ方法で動作します。

PHP については少しだけ触れていますが、3 番目の同時実行インスタンスは PHP/TK です。 PHP/TK は、コア PHP に移植可能なグラフィカル ユーザー インターフェイス (GUI) バインディングを提供する PHP の拡張機能です。 PHP/TK を使用すると、PHP でコードを記述してデスクトップ GUI アプリケーションを構築できます。そのイベントベースの性質により、習得が容易で、スレッドよりもエラーが発生しにくい同時実行の形式がシミュレートされます。さらに、同時実行性は、PHP の基本的な機能ではなく、支援テクノロジから「継承」されています。

PHP 自体にスレッドサポートを追加する実験は何度も行われてきました。私の知る限り、成功した人は一人もいません。ただし、Ajax フレームワークと PHP/TK のイベント指向の実装は、イベントがスレッドよりも PHP の同時実行性をよりよく表現している可能性があることを示唆しています。 PHP V5 は、これが実際に当てはまることを証明しています。標準の PHP V4 以前では、PHP アプリケーションのすべての作業を順番に実行する必要があります。たとえば、プログラムが 2 つのビジネス サイトで品目の価格を取得する必要がある場合、最初のサイトから価格を要求し、応答が到着するまで待機し、次に 2 番目のサイトから価格を要求し、再度待機します。プログラムが複数のタスクを同時に完了するように要求した場合はどうなりますか?全体として、プログラムは一定の期間にわたって完了し、その間には常に継続的な処理が発生します。

最初の PHP スレッドの例 新しい stream_select 関数とそのいくつかのヘルパーにより、これが可能になります。次の例を考えてみましょう。

チェックリスト 1. 複数の HTTP ページを同時にリクエストします

<ol class="dp-xml">
<li class="alt"><span><span><?php  </span></span></li>
<li class=""><span>echo "Program starts at ". date('h:i:s') . ".n";  </span></li>
<li class="alt"><span> </span></li>
<li class="">
<span>$</span><span class="attribute">timeout</span><span>=</span><span class="attribute-value">10</span><span>;  </span>
</li>
<li class="alt">
<span>$</span><span class="attribute">result</span><span>=</span><span class="attribute-value">array</span><span>();  </span>
</li>
<li class="">
<span>$</span><span class="attribute">sockets</span><span>=</span><span class="attribute-value">array</span><span>();  </span>
</li>
<li class="alt">
<span>$</span><span class="attribute">convenient_read_block</span><span>=</span><span class="attribute-value">8192</span><span>;  </span>
</li>
<li class=""><span> </span></li>
<li class="alt"><span>/* Issue all requests simultaneously; there's no blocking. */  </span></li>
<li class="">
<span>$</span><span class="attribute">delay</span><span>=</span><span class="attribute-value">15</span><span>;  </span>
</li>
<li class="alt">
<span>$</span><span class="attribute">id</span><span>=</span><span class="attribute-value">0</span><span>;  </span>
</li>
<li class=""><span>while ($delay > 0) {  </span></li>
<li class="alt">
<span>$</span><span class="attribute">s</span><span>=</span><span class="attribute-value">stream_socket_client</span><span>("phaseit.net:80", $errno,  </span>
</li>
<li class=""><span>$errstr, $timeout,  </span></li>
<li class="alt"><span>STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT);  </span></li>
<li class=""><span>if ($s) {  </span></li>
<li class="alt"><span>$sockets[$id++]=$s;  </span></li>
<li class="">
<span>$</span><span class="attribute">http_message</span><span>=</span><span class="attribute-value">"GET /demonstration/delay?delay="</span><span> .  </span>
</li>
<li class="alt"><span>$delay . " HTTP/1.0rnHost: phaseit.netrnrn";  </span></li>
<li class=""><span>fwrite($s, $http_message);  </span></li>
<li class="alt"><span>} else {  </span></li>
<li class=""><span>echo "Stream " . $id . " failed to open correctly.";  </span></li>
<li class="alt"><span>}  </span></li>
<li class="">
<span>$delay </span><span class="attribute">-</span><span>= </span><span class="attribute-value">3</span><span>;  </span>
</li>
<li class="alt"><span>}  </span></li>
<li class=""><span> </span></li>
<li class="alt"><span>while (count($sockets)) {  </span></li>
<li class="">
<span>$</span><span class="attribute">read</span><span>=$sockets;  </span>
</li>
<li class="alt">
<span>stream_select($read, $</span><span class="attribute">w</span><span>=</span><span class="attribute-value">null</span><span>, $</span><span class="attribute">e</span><span>=</span><span class="attribute-value">null</span><span>, $timeout);  </span>
</li>
<li class=""><span>if (count($read)) {  </span></li>
<li class="alt"><span>/* stream_select generally shuffles $read, so we need to  </span></li>
<li class=""><span>compute from which socket(s) we're reading. */  </span></li>
<li class="alt"><span>foreach ($read as $r) {  </span></li>
<li class="">
<span>$</span><span class="attribute">id</span><span>=</span><span class="attribute-value">array_search</span><span>($r, $sockets);  </span>
</li>
<li class="alt">
<span>$</span><span class="attribute">data</span><span>=</span><span class="attribute-value">fread</span><span>($r, $convenient_read_block);  </span>
</li>
<li class=""><span>/* A socket is readable either because it has  </span></li>
<li class="alt"><span>data to read, OR because it's at EOF. */  </span></li>
<li class=""><span>if (strlen($data) == 0) {  </span></li>
<li class="alt"><span>echo "Stream " . $id . " closes at " . date('h:i:s') . ".n";  </span></li>
<li class=""><span>fclose($r);  </span></li>
<li class="alt"><span>unset($sockets[$id]);  </span></li>
<li class=""><span>} else {  </span></li>
<li class="alt">
<span>$result[$id] </span><span class="attribute">.</span><span>= $data;  </span>
</li>
<li class=""><span>}  </span></li>
<li class="alt"><span>}  </span></li>
<li class=""><span>} else {  </span></li>
<li class="alt"><span>/* A time-out means that *all* streams have failed  </span></li>
<li class=""><span>to receive a response. */  </span></li>
<li class="alt"><span>echo "Time-out!n";  </span></li>
<li class=""><span>break;  </span></li>
<li class="alt"><span>}  </span></li>
<li class=""><span>}  </span></li>
<li class="alt"><span>?>  </span></li>
</ol>
ログイン後にコピー

このチェックリストを実行すると、以下に示す出力が表示されます。


www.bkjia.comtru​​ehttp://www.bkjia.com/PHPjc/446460.html技術記事プロジェクトを実行するときに最初に考慮するのはスレッドです。PHP でスレッドを実装するにはどうすればよいでしょうか。ここでは、PHP スレッドの実装について見ていきます。多くの PHP 開発者は、標準の PHP には行が欠落しているため...
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート