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版
Oct 09 PHP
php将数据库导出成excel的方法
May 07 PHP
PHP无法访问远程mysql的问题分析及解决
May 16 PHP
利用php绘制饼状图的实现代码
Jun 07 PHP
Memcached常用命令以及使用说明详解
Jun 27 PHP
php中sprintf与printf函数用法区别解析
Feb 17 PHP
php防止伪造的数据从URL提交方法
Jun 27 PHP
PHP用反撇号执行外部命令
Apr 14 PHP
php获取从百度、谷歌等搜索引擎进入网站关键词的方法
Jul 08 PHP
PHP session 会话处理函数
Jun 06 PHP
php版微信公众平台回复中文出现乱码问题的解决方法
Sep 22 PHP
PHP面向对象五大原则之里氏替换原则(LSP)详解
Apr 08 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
千呼万唤始出来,DOTA2勇士令状不朽宝藏Ⅱ现已推出
2020/08/25 DOTA
PHP实现对站点内容外部链接的过滤方法
2014/09/10 PHP
解决nginx不支持thinkphp中pathinfo的问题
2015/07/21 PHP
简单的php+mysql聊天室实现方法(附源码)
2016/01/05 PHP
php实用代码片段整理
2016/11/12 PHP
SWFObject Flash js调用类
2008/07/08 Javascript
两个select之间option的互相添加操作(jquery实现)
2009/11/12 Javascript
Javascript中判断变量是数组还是对象(array还是object)
2013/08/14 Javascript
jquery ajax,ashx,json的用法总结
2014/02/12 Javascript
基于iframe实现类似于ajax的页面无刷新
2014/05/31 Javascript
canvas 弹幕效果(实例分享)
2017/01/11 Javascript
js实现二级导航功能
2017/03/03 Javascript
基于Node的React图片上传组件实现实例代码
2017/05/10 Javascript
vue教程之toast弹框全局调用示例详解
2020/08/24 Javascript
vue中设置height:100%无效的问题及解决方法
2018/07/27 Javascript
React如何实现浏览器打印部分内容详析
2019/05/19 Javascript
vue实现文字加密功能
2019/09/27 Javascript
数据挖掘之Apriori算法详解和Python实现代码分享
2014/11/07 Python
python登陆asp网站页面的实现代码
2015/01/14 Python
Django项目实战之用户头像上传与访问的示例
2018/04/21 Python
不知道这5种下划线的含义,你就不算真的会Python!
2018/10/09 Python
python实现K近邻回归,采用等权重和不等权重的方法
2019/01/23 Python
Python中的集合介绍
2019/01/28 Python
浅谈Django2.0 加xadmin踩的坑
2019/11/15 Python
windows10环境下用anaconda和VScode配置的图文教程
2020/03/30 Python
python爬取”顶点小说网“《纯阳剑尊》的示例代码
2020/10/16 Python
html5 Canvas画图教程(11)—使用lineTo/arc/bezierCurveTo画椭圆形
2013/01/09 HTML / CSS
奥兰多迪士尼门票折扣:Undercover Tourist
2018/07/09 全球购物
工作的心得体会
2013/12/31 职场文书
文明礼貌演讲稿
2014/05/12 职场文书
孝敬父母的活动方案
2014/08/31 职场文书
幼儿教师自我剖析材料
2014/09/29 职场文书
教师三严三实心得体会
2014/10/11 职场文书
2014年音乐教师工作总结
2014/12/03 职场文书
家庭教育教师培训学习体会
2016/01/14 职场文书
年会邀请函的格式及范文五篇
2019/11/02 职场文书