socket_set_block関数の主な機能は、ソケットをブロッキングモードに設定することです。ブロッキングモードとは、 socket_readやsocket_writeなどの操作を実行すると、データの準備ができていない場合、データが利用可能になるか操作が完了するまでプログラムが一時停止することを意味します。
<?php
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($socket, "gitbox.net", 80);
socket_set_block($socket);
socket_write($socket, "GET / HTTP/1.1\r\nHost: gitbox.net\r\nConnection: Close\r\n\r\n");
$response = '';
while ($out = socket_read($socket, 2048)) {
$response .= $out;
}
socket_close($socket);
echo $response;
?>
上記のコードでは、 socket_set_blockは、 socket_readがデータの到着を待つことを保証し、すぐには返されません。
ブロッキングモードの利点<br> プログラムがコールをブロックしている場合、CPUはオペレーティングシステムにリリースされ、他のタスクを実行します。言い換えれば、CPUはソケット状態のポーリングに忙しくはありませんが、眠りについて、オペレーティングシステムが利用可能なデータに通知するのを待っています。これにより、CPUの使用量が少なくなり、リソースが合理的に利用されます。
ブロッキングモードの短所<br> ブロッキングとは、プログラムが特定のコールポイントで停止することを意味します。ネットワークまたはピアの応答が遅い場合、プログラムも「スタック」され、他のタスクを処理できません。高い並行性シナリオでは、ブロッキングモードで複数のソケットを使用すると、アプリケーションの応答が遅くなる可能性があります。
ブロッキングモードは自然にCPUの使用を減らすのに役立ちますが、実際のアプリケーションでは異常に高いCPU使用の問題に遭遇する可能性があります。一般的な理由は次のとおりです。
頻繁にブロッキングしない投票(忙しい待機)
開発者が非ブロッキングモードを使用するか、自分でポーリングロジックを実装する場合、プログラムは読み取り関数を呼び出し続け、CPUを忙しくします。
誤ったブロック/非ブロッキングモードの切り替え<br> ソケット状態のスイッチングが頻繁に発生し、適切に制御されていない場合、システムコールの非効率性につながり、CPU負荷が増加する可能性があります。
イベント駆動型または非同期メカニズムがありません<br> ブロッキングのみを使用して、多数のソケットを処理するために使用されるため、プログラムは複数の接続を並行して処理できなくなります。
socket_selectは、複数のソケット状態を聴き、1つ以上のソケットが読みやすく、忙しさを避けるために書き込み可能な場合に動作することができます。
<?php
$read = [$socket];
$write = $except = null;
if (socket_select($read, $write, $except, 5) > 0) {
foreach ($read as $readableSocket) {
$data = socket_read($readableSocket, 2048);
// データの処理
}
}
?>
このようにして、プログラムはソケットにデータがある場合にのみ目が覚め、CPUのアイドル性が低下します。
ブロッキングモードでは、タイムアウトをsocket_set_optionを介して設定して、長期ブロッキングを防ぐことができます。
<?php
socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, ["sec"=>3, "usec"=>0]);
socket_set_option($socket, SOL_SOCKET, SO_SNDTIMEO, ["sec"=>3, "usec"=>0]);
?>
バッファサイズを適切に調整すると、システムコールの数とコンテキストの切り替えも減ることができます。
同時アプリケーションが高い場合、複数のプロセスまたは複数のスレッドを使用して、ブロッキングによって引き起こされるボトルネックを共有して、全体的なパフォーマンスに影響を与えるシングルプロセスブロッキングを回避できます。
PHPには、非ブロッキングおよびイベント駆動型モデルをサポートするSwooleやReactPhpなどの非同期拡張があり、リソースの利用を大幅に改善し、CPU使用を削減します。
socket_set_blockは、ソケット操作をブロックし、CPUのidle性を低下させ、単一接続の効率を向上させます。
ブロッキングモードは、高い並行性シナリオでアプリケーションの応答が遅いことになる場合があります。
Socket_Selectなどの多重化テクノロジーを組み合わせて、タイムアウトパラメーターを合理的に設定すると、CPUの使用量を大幅に削減できます。
非同期またはマルチプロセスモデルを使用することは、パフォーマンスとリソースの利用を改善するための効果的な手段です。
Socket_set_blockがCPUに与える影響の原則を理解し、合理的な最適化を組み合わせることで、PHPネットワークアプリケーションがより効率的で安定性を高めることができます。