详解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实现采集程序原理和简单示例代码
Mar 18 PHP
php表单提交问题的解决方法
Apr 12 PHP
解析php取整的几种方式
Jun 25 PHP
php获取汉字首字母的函数
Nov 07 PHP
php中的filesystem文件系统函数介绍及使用示例
Feb 13 PHP
php实现保存submit内容之后禁止刷新
Mar 19 PHP
php实现的验证码文件类实例
Jun 18 PHP
php算法实例分享
Jul 14 PHP
Yii中srbac权限扩展模块工作原理与用法分析
Jul 14 PHP
thinkphp在php7环境下提示Cannot use ‘String’ as class name as it is reserved的解决方法
Sep 30 PHP
php+redis实现多台服务器内网存储session并读取示例
Jan 12 PHP
微信支付之JSAPI公众号支付详解
May 15 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
十天学会php之第七天
2006/10/09 PHP
PHP生成静态页
2006/11/25 PHP
php中实现简单的ACL 完结篇
2011/09/07 PHP
PHPUnit测试私有属性和方法功能示例
2018/06/12 PHP
PHP内部实现打乱字符串顺序函数str_shuffle的方法
2019/02/14 PHP
js中substring和substr的详细介绍与用法
2013/08/29 Javascript
Jquery使用css方法改变样式实例
2015/05/18 Javascript
jQuery实现图片轮播效果代码(基于jquery.pack.js插件)
2016/06/02 Javascript
Jquery组件easyUi实现手风琴(折叠面板)示例
2016/08/23 Javascript
ionic实现带字的toggle滑动组件
2016/08/27 Javascript
js实现多行文本框统计剩余字数功能
2017/03/28 Javascript
jQuery使用JSONP实现跨域获取数据的三种方法详解
2017/05/04 jQuery
JS+canvas实现的五子棋游戏【人机大战版】
2017/07/19 Javascript
使用Bootstrap4 + Vue2实现分页查询的示例代码
2017/12/21 Javascript
vuex中store存储store.commit和store.dispatch的用法
2020/07/24 Javascript
在vue中使用inheritAttrs实现组件的扩展性介绍
2020/12/07 Vue.js
jQuery实现本地存储
2020/12/22 jQuery
Python如何import文件夹下的文件(实现方法)
2017/01/24 Python
python机器学习之决策树分类详解
2017/12/20 Python
python如何定义带参数的装饰器
2018/03/20 Python
TensorFlow的权值更新方法
2018/06/14 Python
pyqt5与matplotlib的完美结合实例
2019/06/21 Python
python 循环数据赋值实例
2019/12/02 Python
python使用opencv resize图像不进行插值的操作
2020/07/05 Python
基于python实现可视化生成二维码工具
2020/07/08 Python
Kneipp克奈圃美国官网:德国百年精油配方的传承
2018/02/07 全球购物
法国一家多品牌成衣精品中/高档商店:Graduate Store
2019/08/28 全球购物
全球异乡人的跨境社交电商平台:Kouhigh口嗨网
2020/07/24 全球购物
怎样在 Applet 中建立自己的菜单(MenuBar/Menu)?
2012/06/20 面试题
劳资人员岗位职责
2013/12/19 职场文书
"9.18"国耻日演讲稿范文
2014/09/14 职场文书
民主生活会发言材料
2014/10/20 职场文书
2015年重阳节活动总结
2015/03/24 职场文书
化妆品促销活动总结
2015/05/07 职场文书
python自动计算图像数据集的RGB均值
2021/06/18 Python
【海涛DOTA解说】EVE女子战队独家录像加ZSMJ神牛两连发
2022/04/01 DOTA