详解PHP中curl_multi并发的实现


Posted in PHP onJune 08, 2020

PHP中的curl_multi系列函数可以实现同时请求多个URL来实现并发,而不是像普通curl函数那样请求后会阻塞,直到结果返回才进行下一个请求。因此在批量请求URL时可通过curl_multi系列函数提升程序的运行效率。

curl普通请求

$startTime = microtime(true);
$chArr = [];
$optArr = [
  CURLOPT_URL => 'http://www.httpbin.org/ip',
  CURLOPT_HEADER => 0,
  CURLOPT_RETURNTRANSFER => 1,
];
$result = [];

//创建多个curl资源并执行
for ($i=0; $i<10; $i++) {
  $chArr[$i] = curl_init();
  curl_setopt_array($chArr[$i], $optArr);
  $result[$i] = curl_exec($chArr[$i]);
  curl_close($chArr[$i]);
}

$endTime = microtime(true);
echo sprintf("use time: %.3f s".PHP_EOL, $endTime - $startTime);

use time: 6.080 s

curl_multi并发请求

$startTime = microtime(true);
$chArr = [];
$optArr = [
  CURLOPT_URL => 'http://www.httpbin.org/ip',
  CURLOPT_HEADER => 0,
  CURLOPT_RETURNTRANSFER => 1,
];
$result = [];

//创建多个curl资源
for ($i=0; $i<10; $i++) {
  $chArr[$i] = curl_init();
  curl_setopt_array($chArr[$i], $optArr);
}
//创建批处理curl句柄
$mh = curl_multi_init();
//将单个curl句柄添加到批处理curl句柄中
foreach ($chArr as $ch) {
  curl_multi_add_handle($mh, $ch);
}
//判断操作是否仍在执行的标识的引用
$active = null;
/**
 * 本次循环第一次处理 $mh 批处理中的 $ch 句柄,并将 $mh 批处理的执行状态写入 $active,
 * 当状态值等于 CURLM_CALL_MULTI_PERFORM 时,表明数据还在写入或读取中,执行循环,
 * 当第一次 $ch 句柄的数据写入或读取成功后,状态值变为 CURLM_OK ,跳出本次循环,进入下面的大循环中。
 */
do {
  //处理在批处理栈中的每一个句柄
  $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
/**
 * 上面这段代码中,是可以直接使用 $active > 0 来作为 while 的条件,如下:
 * do {
 *  $mrc = curl_multi_exec($mh, $active);
 * } while ($active > 0);
 * 此时如果整个批处理句柄没有全部执行完毕时,系统会不停的执行 curl_multi_exec 函数,从而导致系统CPU占用会很高,
 * 因此一般不采用这种方案,可以通过 curl_multi_select 函数来达到没有需要读取的程序就阻塞住的目的。
 */

/**
 * $active 为 true 时,即 $mh 批处理之中还有 $ch 句柄等待处理,
 * $mrc == CURLM_OK,即上一次 $ch 句柄的读取或写入已经执行完毕。
 */
while ($active && $mrc == CURLM_OK) {
  /** 
   * 程序进入阻塞状态,直到批处理中有活动连接(即 $mh 批处理中还有可执行的 $ch 句柄),
   * 这样执行的好处是 $mh 批处理中的 $ch 句柄会在读取或写入数据结束后($mrc == CURLM_OK)进入阻塞阶段,
   * 而不会在整个 $mh 批处理执行时不停地执行 curl_multi_exec 函数,白白浪费CPU资源。
   */
   if (curl_multi_select($mh) != -1) {
    //程序退出阻塞状态继续执行需要处理的 $ch 句柄
    do {
      $mrc = curl_multi_exec($mh, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
  }
}

foreach ($chArr as $i=>$ch) {
  //获取某个curl句柄的返回值
  $result[$i] = curl_multi_getcontent($ch);
  //移除批处理句柄中的某个句柄资源
  curl_multi_remove_handle($mh, $ch);
}
//关闭一组curl句柄
curl_multi_close($mh);
$endTime = microtime(true);
echo sprintf("use time: %.3f s".PHP_EOL, $endTime - $startTime);

use time: 0.599 s

通过对比上述程序的运行时间可以得知,使用curl_multi系列函数并发请求要比普通的curl函数依次请求效率高很多。

到此这篇关于详解PHP中curl_multi并发的实现的文章就介绍到这了,更多相关PHP curl_multi并发内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木! 

PHP 相关文章推荐
php 时间计算问题小结
Jan 04 PHP
php中的字符编码转换函数用法示例
Oct 20 PHP
PHP原生函数一定好吗?
Dec 08 PHP
php截取中文字符串函数实例
Feb 23 PHP
从wamp到xampp的升级之路
Apr 08 PHP
使用Appcan客户端自动更新PHP版本号(全)
Jul 31 PHP
php强制下载文件函数
Aug 24 PHP
基于CI框架的微信网页授权库示例
Nov 25 PHP
详解PHP swoole process的使用方法
Aug 26 PHP
yii2多图上传组件的使用教程
May 10 PHP
Laravel模糊查询区分大小写的实例
Sep 29 PHP
ThinkPHP5.1+Ajax实现的无刷新分页功能示例
Feb 10 PHP
THINKPHP5.1 Config的配置与获取详解
Jun 08 #PHP
ThinkPHP5.1验证码功能实现的示例代码
Jun 08 #PHP
php框架CI(codeigniter)自动加载与自主创建对象操作实例分析
Jun 06 #PHP
CI框架简单分页类用法示例
Jun 06 #PHP
简单的php购物车代码
Jun 05 #PHP
实例化php类时传参的方法分析
Jun 05 #PHP
PHP页面静态化――纯静态与伪静态用法详解
Jun 05 #PHP
You might like
DOTA2游戏同人动画《龙之血》导演接受采访
2021/03/05 欧美动漫
PHP 文件上传全攻略
2010/04/28 PHP
php定义数组和使用示例(php数组的定义方法)
2014/03/29 PHP
最常用的8款PHP调试工具
2014/07/06 PHP
javascript 有趣而诡异的数组
2009/04/06 Javascript
js静态方法与实例方法分析
2011/07/04 Javascript
stream.js 一个很小、完全独立的Javascript类库
2011/10/28 Javascript
jQuery中创建实例与原型继承揭秘
2011/12/21 Javascript
jQuery 瀑布流 绝对定位布局(二)(延迟AJAX加载图片)
2012/05/23 Javascript
textarea焦点的用法实现获取焦点清空失去焦点提示效果
2014/05/19 Javascript
JQuery做的一个简单的点灯游戏分享
2014/07/16 Javascript
js类式继承与原型式继承详解
2016/04/07 Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
2016/05/30 Javascript
JavaScript获取当前url根目录(路径)
2016/06/17 Javascript
浅谈Javascript事件对象
2017/02/05 Javascript
javascript基础知识之html5轮播图实例讲解(44)
2017/02/17 Javascript
基于Vue2x的图片预览插件的示例代码
2018/05/14 Javascript
vue.js 中使用(...)运算符报错的解决方法
2018/08/09 Javascript
详解Vue CLI3 多页应用实践和源码设计
2018/08/30 Javascript
浅谈VueJS SSR 后端绘制内存泄漏的相关解决经验
2018/12/20 Javascript
基于Vue实现的多条件筛选功能的详解(类似京东和淘宝功能)
2019/05/07 Javascript
vue搜索页开发实例代码详解(热门搜索,历史搜索,淘宝接口演示)
2020/04/11 Javascript
vue项目中使用多选框的实例代码
2020/07/22 Javascript
[36:52]DOTA2真视界:基辅特锦赛总决赛
2017/05/21 DOTA
python爬虫爬取某站上海租房图片
2018/02/04 Python
python3+mysql查询数据并通过邮件群发excel附件
2018/02/24 Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
2018/09/27 Python
在Python中增加和插入元素的示例
2018/11/01 Python
python+opencv像素的加减和加权操作的实现
2019/07/14 Python
Python操作excel的方法总结(xlrd、xlwt、openpyxl)
2019/09/02 Python
用 Django 开发一个 Python Web API的方法步骤
2020/12/03 Python
CSS3 icon font完全指南(CSS3 font 会取代icon图标)
2013/01/06 HTML / CSS
Blank NYC官网:夹克、牛仔裤等
2020/12/16 全球购物
常用UNIX 命令(Linux的常用命令)
2013/07/10 面试题
XX部保密工作制度范本
2019/08/27 职场文书
Tomcat 与 maven 的安装与使用教程
2022/06/16 Servers