現在の位置: ホーム> 最新記事一覧> Multi-CURLリクエストの直後にCurl_Closeがすべての接続を閉じることができないのはなぜですか?

Multi-CURLリクエストの直後にCurl_Closeがすべての接続を閉じることができないのはなぜですか?

gitbox 2025-05-29

PHPでは、CurlはHTTP要求を実行するための非常に一般的なライブラリです。開発者に、他のサーバーと対話するための柔軟で効率的な方法を提供します。通常、 curl_init()を使用してcurlセッションを初期化し、 curl_exec()を使用してリクエストを実行し、 curl_close()を使用してセッションを閉じてリソースを解放します。

ただし、コードで複数のCurlリクエストを実行すると、特に複数の並列リクエストを使用する場合、 Curl_Close()関数を使用してもすぐにすべての接続を閉じないことがわかります。この問題の理由は、Curl要求が非同期に実行され、 Curl_Close()が現在のCurlセッションオブジェクトを閉じるだけで、すぐに下部のすべてのネットワーク接続を破壊することができないためです。

1. Curl要求の非同期実行を説明します

複数のリクエストを実行するとき、特に複数の並列リクエストが行われた場合、これらの要求を処理するためにマルチスレッドメカニズムが使用されます。これらのリクエストは、基礎となる接続プールで管理され、 curl_exec()は、要求が完全に完了したときにすぐに戻りません。実際には、リクエストが完了するのを待っている間、基礎となるネットワーク接続と相互作用します。このプロセスは、 curl_close()によって直接影響を受けません。

2。curl_close ()の役割

curl_close()関数の関数は、Curlセッションを閉じて、セッションに関連するリソースをリリースすることです。ただし、セッションを終了しても、すべての接続がすぐにリリースされることを意味しません。特に、複数の要求が並行して実行される場合、接続のシャットダウンとリソースのリリースが遅延する可能性があります。これは、Curlライブラリが複数のリクエストに接続プールを使用しており、複数のリクエストが完了するまですべての接続をすぐにクリアしないためです。

 // 複数を作成します cURL セッション
$ch1 = curl_init('http://gitbox.net/example1');
$ch2 = curl_init('http://gitbox.net/example2');
$ch3 = curl_init('http://gitbox.net/example3');

// リクエストオプションを設定します
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);

// リクエストを実行して結果を保存します
$response1 = curl_exec($ch1);
$response2 = curl_exec($ch2);
$response3 = curl_exec($ch3);

// 关闭セッション
curl_close($ch1);
curl_close($ch2);
curl_close($ch3);

上記のコードでは、 Curl_Close()を呼び出して各Curlセッションを閉じますが、接続の閉鎖はすぐには発生しません。 Curlは、すべてのリクエストが完了するまで、リクエスト内のいくつかの中間プロセスが処理されるように、最下部に接続を維持し続けます。

3。接続プールとマルチリクエスト管理

効率を向上させるために、特に複数のリクエストが実行される場合、接続プールが維持されます。リクエストが完了するたびに、接続はすぐに閉じられませんが、次の使用のために接続プールに返されます。この接続マルチプレックスメソッドは、各リクエストの接続を再確立する必要がないため、リクエストのパフォーマンスを大幅に向上させます。

ただし、このアプローチは、 curl_close()を介して特定のCurlセッションを閉じますが、接続プールの接続がすべての要求が完了するまでクリーンアップするか、Curlが現在の要求シーケンスを完全に処理することを意味します。

4.すべての接続が閉じられていることを確認する方法

すべての接続が最後に閉じられていることを確認する必要がある場合は、 curl_multi_*関数を使用して複数の並列リクエストを管理できます。 curl_multi_*一連の関数を使用すると、複数のCurlセッションの実行の状態を並行して管理し、接続を閉じる前にすべてのリクエストが完了するようにします。以下に示すように:

 // 複数を作成します cURL セッション
$ch1 = curl_init('http://gitbox.net/example1');
$ch2 = curl_init('http://gitbox.net/example2');
$ch3 = curl_init('http://gitbox.net/example3');

// リクエストオプションを設定します
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);

// aを作成しますcURL多セッション句柄
$mh = curl_multi_init();

// 将セッション添加到多セッション句柄中
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
curl_multi_add_handle($mh, $ch3);

// 执行多セッション请求
do {
    $status = curl_multi_exec($mh, $active);
    if ($active) {
        // リクエストが完了するのを待ちます
        curl_multi_select($mh);
    }
} while ($active);

// 关闭所有セッション
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_remove_handle($mh, $ch3);
curl_multi_close($mh);
curl_close($ch1);
curl_close($ch2);
curl_close($ch3);

curl_multi_*を使用すると、複数のセッションが完了した後、すべての接続が完全にクリーニングおよびクローズされます。これにより、すべてのリクエストが完了すると、基礎となる接続が完全にリリースされます。

結論は

Curlを使用してPHPで複数のリクエストを実行する場合、 Curl_Close()は、特に並列リクエストの場合、すべての接続をすぐに閉じません。これは、Curlが接続プールをマルチプレックス接続に使用し、パフォーマンスを向上させるため、接続の閉鎖が遅れる可能性があるためです。すべての接続を時間内にリリースできるようにするために、 curl_multi_*関数を使用して並列リクエストを管理できるため、すべてのリクエストが完了した後にすべての接続が閉じられるようにします。この方法は、接続リリースの問題を解決するだけでなく、リクエスト実行の効率も向上させます。