<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 次のコンテンツは、記事のメインテキストとは何の関係もありません</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"これが例です PHP コード,記事に関係のない序文を表示するために使用されます。\n"</span></span><span>;
-------------------------------------------------------------------------------
<span class="hljs-comment">/**
* 合格する方法 stream_set_blocking コントロール PHP ソケットの読み取り行動,ネットワークアプリケーションのパフォーマンスを改善します?
*
* 存在する PHP ネットワークプログラミングで,ソケット(socket)読み取り動作は、アプリケーションのパフォーマンスに直接影響を与えます。デフォルトで,
* PHP 的ソケット操作是阻塞式的,つまり、読み取り関数を呼び出すときです(のように fread または stream_get_contents)時間,
* のように果没有数据到达,プログラムは待ちます,データが利用可能になるまで。这种行为存在する高并发または长连接场景下容易导致性能瓶颈。
*
* この問題を解決するために,PHP 提供された stream_set_blocking 関数,可以灵活地コントロールソケット的ブロッキングモード。
*
* 1つ、stream_set_blocking 基本的な使用法
*
* 関数原型:
* bool stream_set_blocking ( resource $stream , int $mode )
*
* パラメーターの説明:
* - $stream: ソケットリソース(stream リソース)。
* - $mode: ブロッキングモード,1 ブロッキングを示します(blocking),0 非ブロッキングを示します(non-blocking)。
*
* 例:
*/</span>
</span><span><span class="hljs-variable">$socket</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_socket_client</span></span><span>(</span><span><span class="hljs-string">"tcp://127.0.0.1:8080"</span></span><span>, </span><span><span class="hljs-variable">$errno</span></span><span>, </span><span><span class="hljs-variable">$errstr</span></span><span>, </span><span><span class="hljs-number">30</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-variable">$socket</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"接続に失敗しました: <span class="hljs-subst">$errstr</span></span></span><span> (</span><span><span class="hljs-subst">$errno</span></span><span>)\n";
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-comment">// 设置非ブロッキングモード</span></span><span>
</span><span><span class="hljs-title function_ invoke__">stream_set_blocking</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-number">0</span></span><span>);
</span><span><span class="hljs-comment">// データを読んでみてください</span></span><span>
</span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fread</span></span><span>(</span><span><span class="hljs-variable">$socket</span></span><span>, </span><span><span class="hljs-number">8192</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$data</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"現在、読みやすいデータはありません,プログラムは引き続き実行されます。\n"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"データを読む: <span class="hljs-subst">$data</span></span></span><span>\n";
}
}
-------------------------------------------------------------------------------
<span class="hljs-comment">/**
* 二、ブロッキングモード与非ブロッキングモード的差异
*
* 1. ブロッキングモード(blocking)
* - fread または fgets 戻る前にデータが到着するのを待ちます。
* - 単一のスレッドに適しています、低い並行シナリオ。
* - 単純,但可能导致长時間间等待阻塞整个脚本。
*
* 2. 非ブロッキングモード(non-blocking)
* - fread 等関数立即返回,若无数据则返回空または false。
* - 非同期処理に適しています、高い並行性シナリオ。
* - 組み合わせることができます stream_select 监控多个ソケット的可读状态,これにより、ネットワークアプリケーションのパフォーマンスが向上します。
*
* 三つ、組み合わせた stream_select パフォーマンスを向上させます
*
* stream_select 複数のストリームが読みやすいかどうかを監視できます、可写または发生异常:
*
* 例:
*/</span>
</span><span><span class="hljs-variable">$read</span></span><span> = [</span><span><span class="hljs-variable">$socket</span></span><span>];
</span><span><span class="hljs-variable">$write</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>;
</span><span><span class="hljs-variable">$except</span></span><span> = </span><span><span class="hljs-literal">null</span></span><span>;
</span><span><span class="hljs-variable">$timeout</span></span><span> = </span><span><span class="hljs-number">2</span></span><span>; </span><span><span class="hljs-comment">// 超時間時間间 2 2番</span></span><span>
</span><span><span class="hljs-variable">$num_changed_streams</span></span><span> = </span><span><span class="hljs-title function_ invoke__">stream_select</span></span><span>(</span><span><span class="hljs-variable">$read</span></span><span>, </span><span><span class="hljs-variable">$write</span></span><span>, </span><span><span class="hljs-variable">$except</span></span><span>, </span><span><span class="hljs-variable">$timeout</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$num_changed_streams</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"监控ソケット出错\n"</span></span><span>;
} </span><span><span class="hljs-keyword">elseif</span></span><span> (</span><span><span class="hljs-variable">$num_changed_streams</span></span><span> === </span><span><span class="hljs-number">0</span></span><span>) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"超時間,まだ読みやすいデータはありません\n"</span></span><span>;
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$read</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$r</span></span><span>) {
</span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fread</span></span><span>(</span><span><span class="hljs-variable">$r</span></span><span>, </span><span><span class="hljs-number">8192</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"受信したデータ: <span class="hljs-subst">$data</span></span></span><span>\n";
}
}
-------------------------------------------------------------------------------
<span class="hljs-comment">/**
* 4、実用的なアプリケーションでのパフォーマンス最適化の提案
*
* 1. 存在する高并发网络应用中,尽量使用非ブロッキングモード读取ソケット,プロセス全体を単一の遅い接続でブロックしないでください。
* 2. 使用 stream_select または类似事件循环机制(のように ReactPHP)来轮询多个ソケット。
* 3. 長いつながりのために,合理设置读取超時間時間间,無限の詰まりを避けてください。
* 4. 避免存在するブロッキングモード下处理大量数据,必要時間可分块读取または使用缓冲。
*
* 合理的な使用によって stream_set_blocking イベントループメカニズム,大幅に改善できます PHP ネットワークアプリケーションの応答速度とスループット。
*/</span>
</span><span><span class="hljs-meta">?></span></span><span>
</span></span>