Curl_mulit

Curl_mulit

curl_init()

$srart_time = microtime(TRUE);
$chArr=[];
//创建多个cURL资源
for($i=0; $i<10; $i++){
    $chArr[$i]=curl_init();
    curl_setopt($chArr[$i], CURLOPT_URL, "http://curl.zhangqiuli.dev.shop/index.php");
    curl_setopt($chArr[$i], CURLOPT_RETURNTRANSFER, 1);//获取页面内容,不输出到页面
    curl_setopt($chArr[$i], CURLOPT_TIMEOUT, 1);
    $result[] = curl_exec($chArr[$i]);
    echo "running ";
}
 print_r($result);
$end_time = microtime(TRUE);
echo sprintf("use time:%.3f s", $end_time - $srart_time);
use time:0.436 s

curl_mulit_ini

$chArr=[];
//创建多个cURL资源
for($i=0; $i<10; $i++){
    $chArr[$i]=curl_init();
    curl_setopt($chArr[$i], CURLOPT_URL, "http://www.52fhy.com/test.json");
    curl_setopt($chArr[$i], CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($chArr[$i], CURLOPT_TIMEOUT, 1);
}
//print_r($chArr);exit;
/*
Array
(
    [0] => Resource id #2
    [1] => Resource id #3
    [2] => Resource id #4
    [3] => Resource id #5
    [4] => Resource id #6
    [5] => Resource id #7
    [6] => Resource id #8
    [7] => Resource id #9
    [8] => Resource id #10
    [9] => Resource id #11
)
*/
$mh = curl_multi_init(); //1 创建批处理cURL句柄

foreach($chArr as $k => $ch){      
    curl_multi_add_handle($mh, $ch); //2 增加句柄
}
$active = null; 
//待优化点:
//在$active > 0,执行curl_multi_exec($mh,$active)而整个批处理句柄没有全部执行完毕时,系统会不停地执行curl_multi_exec()函数。
do{
    echo "running ";
    curl_multi_exec($mh, $active); //3 执行批处理句柄
//    $active ++;
    print_r($active);
}while($active > 0); //4

foreach($chArr as $k => $ch){ 
    $result[$k]= curl_multi_getcontent($ch); //5 获取句柄的返回值
    curl_multi_remove_handle($mh, $ch);//6 将$mh中的句柄移除
}
curl_multi_close($mh); //7 关闭全部句柄 
 print_r($result);
$end_time = microtime(TRUE);
echo sprintf("use time:%.3f s", $end_time - $srart_time);
use time:0.049 s

curl_mulit concurrency optimization curl_mulit_select

As in the previous example where $active > 0, executing curl_multi_exec($mh,$active)the entire batch handle is not all the time is finished, the system will continue to perform curl_multi_exec()the function. This could easily lead to high CPU utilization.

Way is to apply changes in the curl library curl_multi_select () function, which function prototype is as follows:

int curl_multi_select ( resource $mh [, float $timeout = 1.0 ] )

CURL connection block until the batch has an active connection. Number of returned descriptors set descriptor success. On failure, select returns -1 on failure, otherwise a timeout (from the underlying select system call).
I curl_multi_select with them () function to achieve the program does not need to be read on the purpose of blocking live.

$srart_time = microtime(TRUE);
$chArr=[];
//创建多个cURL资源
for($i=0; $i<10; $i++){
    $chArr[$i]=curl_init();
    curl_setopt($chArr[$i], CURLOPT_URL, "http://www.52fhy.com/test.json");
    curl_setopt($chArr[$i], CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($chArr[$i], CURLOPT_TIMEOUT, 1);
}
//print_r($chArr);exit;
/*
Array
(
    [0] => Resource id #2
    [1] => Resource id #3
    [2] => Resource id #4
    [3] => Resource id #5
    [4] => Resource id #6
    [5] => Resource id #7
    [6] => Resource id #8
    [7] => Resource id #9
    [8] => Resource id #10
    [9] => Resource id #11
)
*/
$mh = curl_multi_init(); //1 创建批处理cURL句柄

foreach($chArr as $k => $ch){      
    curl_multi_add_handle($mh, $ch); //2 增加句柄
}
$active = null; 
//CURLM_CALL_MULTI_PERFORM 没有要处理的句柄时候 返回CURLM_OK 
do{
    echo "running ";
    $mrc = curl_multi_exec($mh, $active); //3 执行批处理句柄
}while ($mrc == CURLM_CALL_MULTI_PERFORM); //4

//本次循环第一次处理$mh批处理中的$ch句柄,并将$mh批处理的执行状态写入$active ,当状态值等于CURLM_CALL_MULTI_PERFORM时,表明数据还在写入或读取中,执行循环,当第一次$ch句柄的数据写入或读取成功后,状态值变为CURLM_OK,跳出本次循环,进入下面的大循环之中。

//$active 为true,即$mh批处理之中还有$ch句柄正待处理,$mrc==CURLM_OK,即上一次$ch句柄的读取或写入已经执行完毕。
while ($active && $mrc == CURLM_OK) { 
    if (curl_multi_select($mh) != -1) {//$mh批处理中还有可执行的$ch句柄,curl_multi_select($mh) != -1程序退出阻塞状态。
        do {
            $mrc = curl_multi_exec($mh, $active);//继续执行需要处理的$ch句柄。
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}
foreach($chArr as $k => $ch){ 
    $result[$k]= curl_multi_getcontent($ch); //5 获取句柄的返回值
    curl_multi_remove_handle($mh, $ch);//6 将$mh中的句柄移除
}
curl_multi_close($mh); //7 关闭全部句柄 
 print_r($result);
$end_time = microtime(TRUE);
echo sprintf("use time:%.3f s", $end_time - $srart_time);
use time:0.100 s
use time:0.073 s
use time:0.089 s
use time:0.056 s

Higher than the previous optimization did above, but does not soar cpu

The benefits of this execution is a $mhbatch $chhandle will (after the end of the reading or writing data $mrc==CURLM_OK) into the curl_multi_select($mh)blocking stage, but not in the whole $mhconstantly perform curl_multi_exec batch execution time, a waste of CPU resources.

curl_mulit concurrent optimized rolling

The above example there is room for optimization, as quickly as possible to deal with it when optimizing the way when a URL request is completed, while other processing while waiting for the return URL, rather than waiting for the process began after the slowest interfaces return etc., in order to avoid CPU idle and waste.

<?php
$srart_time = microtime(TRUE);
$chArr=[];
//创建多个cURL资源
for($i=0; $i<10; $i++){
    $chArr[$i]=curl_init();
    curl_setopt($chArr[$i], CURLOPT_URL, "http://www.52fhy.com/test.json");
    curl_setopt($chArr[$i], CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($chArr[$i], CURLOPT_TIMEOUT, 1);
}
//print_r($chArr);exit;
/*
Array
(
    [0] => Resource id #2
    [1] => Resource id #3
    [2] => Resource id #4
    [3] => Resource id #5
    [4] => Resource id #6
    [5] => Resource id #7
    [6] => Resource id #8
    [7] => Resource id #9
    [8] => Resource id #10
    [9] => Resource id #11
)
*/
$mh = curl_multi_init(); //1 创建批处理cURL句柄

foreach($chArr as $k => $ch){      
    curl_multi_add_handle($mh, $ch); //2 增加句柄
}
$active = null; 

do {
    while (($mrc = curl_multi_exec($mh, $active)) == CURLM_CALL_MULTI_PERFORM) ;

    if ($mrc != CURLM_OK) { break; }

    // a request was just completed -- find out which one
    while ($done = curl_multi_info_read($mh)) {

        // get the info and content returned on the request
        $info = curl_getinfo($done['handle']);
        $error = curl_error($done['handle']);
        $result[] = curl_multi_getcontent($done['handle']);
        // $responses[$map[(string) $done['handle']]] = compact('info', 'error', 'results');

        // remove the curl handle that just completed
        curl_multi_remove_handle($mh, $done['handle']);
        curl_close($done['handle']);
    }

    // Block for data in / output; error handling is done by curl_multi_exec
    if ($active > 0) {
        curl_multi_select($mh);
    }

} while ($active);

print_r($result);
$end_time = microtime(TRUE);
echo sprintf("use time:%.3f s", $end_time - $srart_time);


use time:0.057 s

Reprint, if wrong, please contact deleted!

https://www.cnblogs.com/52fhy/p/8908315.html

Published 55 original articles · won praise 40 · views 6657

Guess you like

Origin blog.csdn.net/qq_39787367/article/details/103995166