侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

php  /  管理员 发布于 7年前   170

本文实例讲述了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网页的内容。

程序代码如下:

";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 "
";$mtime_ = explode(" ", microtime());$mtime_ = $mtime_[1].($mtime_[0] * 1000);$mtime2_ = explode(".", $mtime_);$mtime_ = $mtime2_[0];echo $mtime_;echo "
";echo $mtime_ - $mtime;}?>

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

代码如下:

";$mtime = explode(" ", microtime());$mtime = $mtime[1].($mtime[0] * 1000);$mtime2 = explode(".", $mtime);$mtime = $mtime2[0];echo $mtime;echo "
";$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] => example2echo "
";echo date("Y-m-d H:m:s",time());echo " ";echo floor(microtime()*1000);echo "
";$mtime_ = explode(" ", microtime());$mtime_ = $mtime_[1].($mtime_[0] * 1000);$mtime2_ = explode(".", $mtime_);$mtime_ = $mtime2_[0];echo $mtime_;echo "
";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_multi_add_handle
  • 这一步需要注意的是,curl_multi_add_handle的第二个参数是由curl_init而来的子handle。
  • 第三步:持续调用curl_multi_exec
  • 第四步:根据需要循环调用curl_multi_getcontent获取结果
  • 第五步:调用curl_multi_remove_handle,并为每个字handle调用curl_close
  • 第六步:调用curl_multi_close

各函数作用解释:

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_MULTI实现多线程采集的例子
  • PHP Curl多线程原理实例详解
  • PHP使用CURL实现多线程抓取网页
  • php结合curl实现多线程抓取
  • php中foreach结合curl实现多线程的方法分析
  • PHP CURL 多线程操作代码实例
  • 浅谈php使用curl模拟多线程发送请求
  • php curl批处理实现可控并发异步操作示例
  • PHP curl批处理及多请求并发实现方法分析
  • PHP中使用CURL发送get/post请求上传图片批处理功能
  • php使用curl模拟多线程实现批处理功能示例


  • 上一条:
    php实现的rc4加密解密类定义与用法示例
    下一条:
    php使用curl获取header检测开启GZip压缩的方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 用Time Warden监控PHP中的代码处理时间(0个评论)
    • 在PHP中使用array_pop + yield实现读取超大型目录功能示例(0个评论)
    • Property Hooks RFC在PHP 8.4中越来越接近现实(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(95个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2017-06
    • 2017-07
    • 2017-08
    • 2017-09
    • 2017-11
    • 2017-12
    • 2018-01
    • 2018-02
    • 2018-03
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-09
    • 2021-02
    • 2021-03
    • 2021-04
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-09
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-09
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客