PHP使用curl_multi_select解决curl_multi网页假死问题的方法


Posted in PHP onAugust 15, 2018

本文实例讲述了PHP使用curl_multi_select解决curl_multi网页假死问题的方法。分享给大家供大家参考,具体如下:

curl_multi可以批处理事务,给网页编程带来很大的方便。不过在使用curl_multi的过程中,我们会遇到一个比较头疼的问题,那就是当并发处理的事务数量过多的时候,就会出现CPU过高,网页假死的现象,这是不可以忽视的。

今天,通过查询相关资料和测试,终于找到了一个解决问题的方法。

正常情况下,我们是这样使用curl_multi的。

实例代码:

$connomains = array(
"//3water.com/",
"http://www.163.com/",
"http://www.sina.com.cn/"
);
$mh = curl_multi_init();
foreach ($connomains as $i => $url) {
   $conn[$i]=curl_init($url);
   curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,1);
   curl_multi_add_handle ($mh,$conn[$i]);
}
do { $n=curl_multi_exec($mh,$active); } while ($active);
foreach ($connomains as $i => $url) {
   $res[$i]=curl_multi_getcontent($conn[$i]);
   curl_close($conn[$i]);
}
print_r($res);

这个实例代码有个致命弱点,就是在do循环的那段,在整个url请求期间是个死循环,它会轻易导致CPU占用很高,网页出现假死状态。

经过测试发现,我们可以巧妙使用curl_multi_select()函数来解决这个问题。

方法如下:

do { $n=curl_multi_exec($mh,$active); } while ($active);

改为

do {
   $mrc = curl_multi_exec($mh,$active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active and $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
      do {
          $mrc = curl_multi_exec($mh, $active);
      } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

因为$active要等全部url数据接受完毕才变成false,所以这里用到了curl_multi_exec的返回值判断是否还有数据,当有数据的时候就不停调用curl_multi_exec,暂时没有数据就进入select阶段,新数据一来就可以被唤醒继续执行。这里的好处就是CPU的无谓消耗没有了。

另外可能遇到的问题:

控制每一个请求的超时时间,在curl_multi_add_handle之前通过curl_setopt去做:

curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);

判断是否超时了或者其他错误,在curl_multi_getcontent之前用:

curl_error($conn[$i]);

了解multi接口

当程序需要进行多次curl并发请求的时候,curl提供的multi接口就派上用场了。流畅大致是这样的:

1)、curl_multi _init初始化一个multi curl对象,为了同时进行多个curl的并发访问,我们需要初始化多个easy curl对象,使用curl_easy_setopt进行相关设置。

2)、调用curl_multi _add_handle把easy curl对象添加到multi curl对象中。

3)、添加完毕后执行curl_multi_perform方法进行并发的访问。

4)、访问结束后curl_multi_remove_handle移除相关easy curl对象,curl_easy_cleanup清除easy curl对象。

5)、最后curl_multi_cleanup清除multi curl对象。

一个简单明了的PHP使用curl_multi_add_handle并行处理实例

<?php
// 创建一对cURL资源
$ch1 = curl_init();
$ch2 = curl_init();
// 设置URL和相应的选项
curl_setopt($ch1, CURLOPT_URL, "//3water.com/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_URL, "http://www.baidu.com/");
curl_setopt($ch2, CURLOPT_HEADER, 0);
// 创建批处理cURL句柄
$mh = curl_multi_init();
// 增加2个句柄
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
$running=null;
// 执行批处理句柄
do {
  curl_multi_exec($mh,$running);
} while($running > 0);
// 关闭全部句柄
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
?>

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
IIS+PHP+MySQL+Zend配置 (视频教程)
Dec 13 PHP
php 需要掌握的东西 不做浮躁的人
Dec 28 PHP
php学习笔记 数组遍历实现代码
Jun 09 PHP
PHP数组无限分级数据的层级化处理代码
Dec 29 PHP
ThinkPHP的RBAC(基于角色权限控制)深入解析
Jun 17 PHP
async和DOM Script文件加载比较
Jul 20 PHP
PHP生成制作验证码的简单实例
Jun 12 PHP
Laravel如何使用数据库事务及捕获事务失败后的异常详解
Oct 23 PHP
PHP实现Huffman编码/解码的示例代码
Apr 20 PHP
php实现在线考试系统【附源码】
Sep 18 PHP
PHP发送邮件确认验证注册功能示例【修改别人邮件类】
Nov 09 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
Mar 24 PHP
php+croppic.js实现剪切上传图片功能
Aug 14 #PHP
PHP设计模式之委托模式定义与用法简单示例
Aug 13 #PHP
PHP设计模式之建造者模式定义与用法简单示例
Aug 13 #PHP
PHP设计模式之装饰器模式定义与用法简单示例
Aug 13 #PHP
PHP实现的ID混淆算法类与用法示例
Aug 10 #PHP
PHP+ajax实现二级联动菜单功能示例
Aug 10 #PHP
PHP实现十进制数字与二十六进制字母串相互转换操作示例
Aug 10 #PHP
You might like
一个PHP缓存类代码(附详细说明)
2011/06/09 PHP
php搜索文件程序分享
2015/10/30 PHP
php中替换字符串函数strtr()和str_repalce()的用法与区别
2016/11/25 PHP
PHP 文件锁与进程锁的使用示例
2017/08/07 PHP
PHP PDOStatement::errorCode讲解
2019/01/31 PHP
Yii2框架控制器、路由、Url生成操作示例
2019/05/27 PHP
JavaScript 保存数组到Cookie的代码
2010/04/14 Javascript
JQuery 操作select标签实现代码
2010/05/14 Javascript
JavaScript高级程序设计(第3版)学习笔记6 初识js对象
2012/10/11 Javascript
JavaScript中字符串(string)转json的2种方法
2015/06/25 Javascript
JavaScript语言精粹经典实例(整理篇)
2016/06/07 Javascript
Web开发使用Angular实现用户密码强度判别的方法
2017/09/27 Javascript
利用pm2部署多个node.js项目的配置教程
2017/10/22 Javascript
webpack+vue中使用别名路径引用静态图片地址
2017/11/20 Javascript
JS中this的指向以及call、apply的作用
2018/05/06 Javascript
Vue-router 中hash模式和history模式的区别
2018/07/24 Javascript
基于Vue的商品主图放大镜方案详解
2019/09/19 Javascript
十分钟教你上手ES2020新特性
2020/02/12 Javascript
使用pandas模块读取csv文件和excel表格,并用matplotlib画图的方法
2018/06/22 Python
Python列表(List)知识点总结
2019/02/18 Python
解决python3中的requests解析中文页面出现乱码问题
2019/04/19 Python
OpenCV搞定腾讯滑块验证码的实现代码
2019/05/18 Python
python切片的步进、添加、连接简单操作示例
2019/07/11 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
2020/02/12 Python
Pytorch使用PIL和Numpy将单张图片转为Pytorch张量方式
2020/05/25 Python
keras读取训练好的模型参数并把参数赋值给其它模型详解
2020/06/15 Python
完美解决TensorFlow和Keras大数据量内存溢出的问题
2020/07/03 Python
CSS3制作精致的照片墙特效
2016/06/07 HTML / CSS
使用CSS3创建动态菜单效果
2015/07/10 HTML / CSS
通过css3的filter滤镜改变png图片的颜色的示例代码
2020/05/06 HTML / CSS
俄罗斯天然和有机产品、健康生活网上商店:Fitomarket.ru
2020/10/09 全球购物
保卫钓鱼岛口号
2014/06/20 职场文书
2015年毕业生自荐信范文
2015/03/24 职场文书
婚礼嘉宾致辞
2015/07/28 职场文书
SQL使用复合索引实现数据库查询的优化
2022/05/25 SQL Server
Python如何加载模型并查看网络
2022/07/15 Python