• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    php使用curl_init()和curl_multi_init()多线程的速度比较详解

    本文实例讲述了php使用curl_init()和curl_multi_init()多线程的速度比较。分享给大家供大家参考,具体如下:

    php中curl_init()的作用很大,尤其是在抓取网页内容或文件信息的时候,例如之前文章《php使用curl获取header检测开启GZip压缩》就介绍到curl_init()的强大。

    curl_init()处理事物是单线程模式,如果需要对事务处理走多线程模式,那么php里提供了一个函数curl_multi_init()给我们,这就是多线程模式处理事务的函数。

    curl_init()curl_multi_init()的速度比较

    curl_multi_init()多线程能提高网页的处理速度吗?今天我通过实验来验证一下这个问题。

    今天我的测试很简单,那就是要抓取www.webkaka.com网页的内容,要连续抓5次,分别用curl_init()curl_multi_init()函数来完成,记录两者的耗时,比较得出结论。

    首先,用curl_init()单线程连续抓5次www.webkaka.com网页的内容。

    程序代码如下:

    ?php
    $mtime = explode(" ", microtime());
    $mtime = $mtime[1].($mtime[0] * 1000);
    $mtime2 = explode(".", $mtime);
    $mtime = $mtime2[0];
    echo $mtime;
    echo "br>";
    for($i=1; $i=5; $i++){
    $szUrl = 'http://www.webkaka.com/';
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $szUrl);
    curl_setopt($curl, CURLOPT_HEADER, 0);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_ENCODING, '');
    $data=curl_exec($curl);
    echo $data;
    echo "br>";
    $mtime_ = explode(" ", microtime());
    $mtime_ = $mtime_[1].($mtime_[0] * 1000);
    $mtime2_ = explode(".", $mtime_);
    $mtime_ = $mtime2_[0];
    echo $mtime_;
    echo "br>";
    echo $mtime_ - $mtime;
    }
    ?>
    
    

    然后,用curl_multi_init()多线程连续抓5次www.webkaka.com网页的内容。

    代码如下:

    ?php
    echo date("Y-m-d H:m:s",time());
    echo " ";
    echo floor(microtime()*1000);
    echo "br>";
    $mtime = explode(" ", microtime());
    $mtime = $mtime[1].($mtime[0] * 1000);
    $mtime2 = explode(".", $mtime);
    $mtime = $mtime2[0];
    echo $mtime;
    echo "br>";
    $urls = array(
    'http://www.webkaka.com',
    'http://www.webkaka.com',
    'http://www.webkaka.com',
    'http://www.webkaka.com',
    'http://www.webkaka.com');
    print_r(async_get_url($urls)); // [0] => example1, [1] => example2
    echo "br>";
    echo date("Y-m-d H:m:s",time());
    echo " ";
    echo floor(microtime()*1000);
    echo "br>";
    $mtime_ = explode(" ", microtime());
    $mtime_ = $mtime_[1].($mtime_[0] * 1000);
    $mtime2_ = explode(".", $mtime_);
    $mtime_ = $mtime2_[0];
    echo $mtime_;
    echo "br>";
    echo $mtime_ - $mtime;
    function async_get_url($url_array, $wait_usec = 0)
    {
      if (!is_array($url_array))
        return false;
      $wait_usec = intval($wait_usec);
      $data  = array();
      $handle = array();
      $running = 0;
      $mh = curl_multi_init(); // multi curl handler
      $i = 0;
      foreach($url_array as $url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don't print
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
        curl_setopt($ch, CURLOPT_MAXREDIRS, 7);
        curl_multi_add_handle($mh, $ch); // 把 curl resource 放进 multi curl handler 里
        $handle[$i++] = $ch;
      }
      /* 执行 */
      do {
        curl_multi_exec($mh, $running);
        if ($wait_usec > 0) /* 每个 connect 要间隔多久 */
          usleep($wait_usec); // 250000 = 0.25 sec
      } while ($running > 0);
      /* 读取资料 */
      foreach($handle as $i => $ch) {
        $content = curl_multi_getcontent($ch);
        $data[$i] = (curl_errno($ch) == 0) ? $content : false;
      }
      /* 移除 handle*/
      foreach($handle as $ch) {
        curl_multi_remove_handle($mh, $ch);
      }
      curl_multi_close($mh);
      return $data;
    }
    ?>
    
    

    为了避免随机性,我分别测了5次(用CTRL+F5强行刷新的方式),数据如下:

    curl_init():

    第一次 第二次 第三次 第四次 第五次 平均
    耗时(ms) 3724 3615 2540 1957 2794 2926

    curl_multi_init():

    第一次 第二次 第三次 第四次 第五次 平均
    耗时(ms) 4275 2912 3691 4198 3891 3793

    从测试结果来看,我们发现两种方法的耗时差不了太多,只有700多毫秒。很多人原本以为多线程比单线程耗时会短很多,实际上并不是这样的,从数据来看,多线程反而比单线程耗时更多了一点。不过,对于某些事务来说,用多线程来处理不一定是为了追求速度,这个是需要注意的。

    关于curl_multi_init()

    一般来说,想到要用curl_multi_init()时,目的是要同时请求多个url,而不是一个一个依次请求,否则就要curl_init()了。

    不过,在使用curl_multi的时候,你可能遇到cpu消耗过高、网页假死等现象,可以看看《PHP使用curl_multi_select解决curl_multi网页假死问题》

    使用curl_multi的步骤总结如下:

    各函数作用解释:

    curl_multi_init()
    初始化一个curl批处理句柄资源。

    curl_multi_add_handle()
    向curl批处理会话中添加单独的curl句柄资源。curl_multi_add_handle()函数有两个参数,第一个参数表示一个curl批处理句柄资源,第二个参数表示一个单独的curl句柄资源。

    curl_multi_exec()
    解析一个curl批处理句柄,curl_multi_exec()函数有两个参数,第一个参数表示一个批处理句柄资源,第二个参数是一个引用值的参数,表示剩余需要处理的单个的curl句柄资源数量。

    curl_multi_remove_handle()
    移除curl批处理句柄资源中的某个句柄资源,curl_multi_remove_handle()函数有两个参数,第一个参数表示一个curl批处理句柄资源,第二个参数表示一个单独的curl句柄资源。

    curl_multi_close()
    关闭一个批处理句柄资源。

    curl_multi_getcontent()
    在设置了CURLOPT_RETURNTRANSFER的情况下,返回获取的输出的文本流。

    curl_multi_info_read()
    获取当前解析的curl的相关传输信息。

    实例

    请看本文里async_get_url()的写法。

    更多关于PHP相关内容感兴趣的读者可查看本站专题:《php curl用法总结》、《PHP网络编程技巧总结》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《PHP数据结构与算法教程》及《PHP中json格式数据操作技巧汇总》

    希望本文所述对大家PHP程序设计有所帮助。

    您可能感兴趣的文章:
    • 浅谈php使用curl模拟多线程发送请求
    • 实例讲解php实现多线程
    • PHP多线程模拟实现秒杀抢单
    • PHP7多线程搭建教程
    • PHP中多线程的两个实现方法
    • php与python实现的线程池多线程爬虫功能示例
    • php多线程并发实现方法
    • php中foreach结合curl实现多线程的方法分析
    • 如何用PHP实现多线程编程
    上一篇:php使用curl获取header检测开启GZip压缩的方法
    下一篇:PHP curl批处理及多请求并发实现方法分析
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    php使用curl_init()和curl_multi_init()多线程的速度比较详解 php,使用,curl,init,和,multi,