详解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中使用临时表查询数据的一个例子
Feb 03 PHP
用Php编写注册后Email激活验证的实例代码
Mar 11 PHP
PHP的构造方法,析构方法和this关键字详细介绍
Oct 22 PHP
带密匙的php加密解密示例分享
Jan 29 PHP
php实现在限定区域里自动调整字体大小的类实例
Apr 02 PHP
thinkPHP多语言切换设置方法详解
Nov 11 PHP
PHP 中使用ajax时一些常见错误总结整理
Feb 27 PHP
php mysql_list_dbs()函数用法示例
Mar 29 PHP
PHP实现webshell扫描文件木马的方法
Jul 31 PHP
PHP与以太坊交互详解
Aug 24 PHP
Thinkphp5+plupload实现的图片上传功能示例【支持实时预览】
May 08 PHP
Thinkphp5.0 框架使用模型Model添加、更新、删除数据操作详解
Oct 11 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
mysql 的 like 问题,超强毕杀记!!!
2007/01/18 PHP
php+javascript实现的动态显示服务器运行程序进度条功能示例
2017/08/07 PHP
javascript中的void运算符语法及使用介绍
2013/03/10 Javascript
JS实现点击按钮获取页面高度的方法
2015/11/02 Javascript
JS验证邮件地址格式方法小结
2015/12/01 Javascript
JavaScript实现跑马灯抽奖活动实例代码解析与优化(二)
2016/02/16 Javascript
jquery通过name属性取值的简单实现方法
2016/06/20 Javascript
详谈javascript精度问题与调整
2017/07/08 Javascript
深入理解Vue-cli搭建项目后的目录结构探秘
2017/07/13 Javascript
iframe高度自适应及隐藏滚动条的实例详解
2017/09/29 Javascript
JavaScript简单实现合并两个Json对象的方法示例
2017/10/16 Javascript
Vue.js 的移动端组件库mint-ui实现无限滚动加载更多的方法
2017/12/23 Javascript
JS使用canvas中的measureText方法测量字体宽度示例
2019/02/02 Javascript
如何优雅地在vue中添加权限控制示例详解
2019/03/07 Javascript
vue配置多代理服务接口地址操作
2020/09/08 Javascript
[00:49]完美世界DOTA2联赛10月28日开团时刻:随便打
2020/10/29 DOTA
python获取元素在数组中索引号的方法
2015/07/15 Python
好用的Python编辑器WingIDE的使用经验总结
2016/08/31 Python
python装饰器-限制函数调用次数的方法(10s调用一次)
2018/04/21 Python
Python爬虫包BeautifulSoup学习实例(五)
2018/06/17 Python
PyCharm永久激活方式(推荐)
2020/09/22 Python
全网首秀之Pycharm十大实用技巧(推荐)
2020/04/27 Python
Python中的wordcloud库安装问题及解决方法
2020/05/27 Python
CSS3 特效范例整理
2011/08/22 HTML / CSS
HTML5 3D衣服摇摆动画特效
2016/03/17 HTML / CSS
美国知名的家庭连锁百货商店:Boscov’s
2017/07/27 全球购物
VICHY薇姿美国官方网站:欧洲药房第一的抗衰老品牌
2017/11/22 全球购物
屈臣氏泰国官网:Watsons TH
2021/02/23 全球购物
演讲稿开场白
2014/01/13 职场文书
学习标兵获奖感言
2014/02/20 职场文书
经贸专业毕业生求职信范文
2014/05/01 职场文书
安全生产宣传标语
2014/06/06 职场文书
走群众路线学习笔记
2014/11/06 职场文书
资金申请报告范文
2015/05/14 职场文书
纯html+css实现打字效果
2021/08/02 HTML / CSS
Mysql超详细讲解死锁问题的理解
2022/04/01 MySQL