详解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编码规范-php coding standard
Mar 16 PHP
删除html标签得到纯文本可处理嵌套的标签
Apr 28 PHP
php环境无法上传文件的解决方法
Apr 30 PHP
让CodeIgniter的ellipsize()支持中文截断的方法
Jun 12 PHP
php采集自中央气象台范围覆盖全国的天气预报代码实例
Jan 04 PHP
PHP中ID设置自增后不连续的原因分析及解决办法
Aug 21 PHP
php简单截取字符串代码示例
Oct 19 PHP
详解PHP编码转换函数应用技巧
Oct 22 PHP
AJAX的使用方法详解
Apr 29 PHP
php 生成加密公钥加密私钥实例详解
Jun 16 PHP
PHP多维数组排序array详解
Nov 21 PHP
PHP反射学习入门示例
Jun 14 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数组的使用方法小结
2010/09/23 PHP
php实现refresh刷新页面批量导入数据的方法
2014/12/23 PHP
简单谈谈PHP中的include、include_once、require以及require_once语句
2016/04/23 PHP
php利用imagemagick实现复古老照片效果实例
2017/02/16 PHP
DOM精简教程
2006/10/03 Javascript
javaScript 简单验证代码(用户名,密码,邮箱)
2009/09/28 Javascript
JS实现的生成随机数的4个函数分享
2015/02/11 Javascript
JavaScript中匿名函数用法实例
2015/03/23 Javascript
js兼容火狐获取图片宽和高的方法
2015/05/21 Javascript
jQuery返回定位插件详解
2017/05/15 jQuery
微信小程序Echarts覆盖正常组件问题解决
2019/07/13 Javascript
对layui数据表格动态cols(字段)动态变化详解
2019/10/25 Javascript
JQuery常用选择器功能与用法实例分析
2019/12/23 jQuery
Vue 基于 vuedraggable 实现选中、拖拽、排序效果
2020/05/18 Javascript
如何在Vue.JS中使用图标组件
2020/08/04 Javascript
使用Python进行二进制文件读写的简单方法(推荐)
2016/09/12 Python
分析python切片原理和方法
2017/12/19 Python
python之DataFrame实现excel合并单元格
2021/02/22 Python
tensorflow 输出权重到csv或txt的实例
2018/06/14 Python
Pandas DataFrame 取一行数据会得到Series的方法
2018/11/10 Python
python日期与时间戳的各种转换示例
2020/02/12 Python
CSS3 圆角效果
2009/07/15 HTML / CSS
CSS3 Pie工具推荐--让IE6-8支持一些优秀的CSS3特性
2014/09/02 HTML / CSS
利用CSS3的border-radius绘制太极及爱心图案示例
2016/05/17 HTML / CSS
AmazeUi Tree(树形结构) 应用小结
2020/08/17 HTML / CSS
深圳-东方伟业笔试部分
2015/02/11 面试题
师范大学毕业自我鉴定
2013/11/21 职场文书
中国梦演讲稿开场白
2014/08/28 职场文书
交通工程专业推荐信
2014/09/06 职场文书
领导干部作风建设工作总结
2014/10/23 职场文书
美丽人生观后感
2015/06/03 职场文书
舞出我人生观后感
2015/06/16 职场文书
领导干部学习心得体会
2016/01/23 职场文书
PHP中->和=>的意思
2021/03/31 PHP
Nginx配置并兼容HTTP实现代码解析
2021/03/31 Servers
PHP获取学生成绩的方法
2021/11/17 PHP