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 相关文章推荐
php 论坛采集程序 模拟登陆,抓取页面 实现代码
Jul 09 PHP
Can't create/write to file 'C:\WINDOWS\TEMP\...MYSQL报错解决方法
Jun 30 PHP
PHP去掉从word直接粘贴过来的没有用格式的函数
Oct 29 PHP
深入php函数file_get_contents超时处理的方法详解
Jun 03 PHP
zf框架的registry(注册表)使用示例
Mar 13 PHP
PHP采用自定义函数实现遍历目录下所有文件的方法
Aug 19 PHP
php简单防盗链实现方法
Jul 29 PHP
yii 2.0中表单小部件的使用方法示例
May 23 PHP
Thinkphp5 微信公众号token验证不成功的原因及解决方法
Nov 12 PHP
Laravel框架实现超简单的分页效果示例
Feb 08 PHP
ThinkPHP5.1框架数据库链接和增删改查操作示例
Aug 03 PHP
redis+php实现微博(二)发布与关注功能详解
Sep 23 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手册及PHP编程标准
2006/12/17 PHP
php简单静态页生成过程
2008/03/27 PHP
关于php 接口问题(php接口主要也就是运用curl,curl函数)
2013/07/01 PHP
php计算两个日期相差天数的方法
2015/03/14 PHP
Asp.net下利用Jquery Ajax实现用户注册检测(验证用户名是否存)
2010/09/12 Javascript
C#中TrimStart,TrimEnd,Trim在javascript上的实现
2011/01/17 Javascript
再论Javascript下字符串连接的性能
2011/03/05 Javascript
Jquery原生态实现表格header头随滚动条滚动而滚动
2014/03/18 Javascript
JavaScript匿名函数之模仿块级作用域
2015/12/12 Javascript
超赞的jQuery图片滑块动画特效代码汇总
2016/01/25 Javascript
Kindeditor在线文本编辑器如何过滤HTML
2016/04/14 Javascript
Bootstrap3使用typeahead插件实现自动补全功能
2016/07/07 Javascript
使用Vue.js和Element-UI做一个简单登录页面的实例
2018/02/23 Javascript
浅谈vue同一页面中拥有两个表单时,的验证问题
2018/09/18 Javascript
Vuex中的State使用介绍
2019/01/19 Javascript
element-ui表格合并span-method的实现方法
2019/05/21 Javascript
JS根据json数组多个字段排序及json数组常用操作
2019/06/06 Javascript
Vue学习之axios的使用方法实例分析
2020/01/06 Javascript
javascript实现蒙版与禁止页面滚动
2020/01/11 Javascript
如何通过javaScript去除字符串两端的空白字符
2020/02/06 Javascript
vue 微信分享回调iOS和安卓回调出现错误的解决
2020/09/07 Javascript
python构建自定义回调函数详解
2017/06/20 Python
理论讲解python多进程并发编程
2018/02/09 Python
基于python 凸包问题的解决
2020/04/16 Python
一文读懂python Scrapy爬虫框架
2021/02/24 Python
CSS3中的clip-path使用攻略
2015/08/03 HTML / CSS
会计学财务管理专业个人的自我评价
2013/10/19 职场文书
学习十八大报告感言
2014/02/04 职场文书
2014迎新年晚会策划方案
2014/02/23 职场文书
幼儿园教师的考核评语
2014/04/18 职场文书
实习生矿工检讨书
2014/10/13 职场文书
课堂打架检讨书200字
2014/11/21 职场文书
校友回访母校寄语
2015/02/26 职场文书
2015年班干部工作总结
2015/04/29 职场文书
求职信:会计求职的写作技巧
2019/04/24 职场文书
java解析XML详解
2021/07/09 Java/Android