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 include的妙用,实现路径加密
Jul 29 PHP
php 图像函数大举例(非原创)
Jun 20 PHP
php比较两个绝对时间的大小
Jan 31 PHP
php无限遍历目录示例
Feb 21 PHP
ThinkPHP惯例配置文件详解
Jul 14 PHP
PHP return语句另类用法不止是在函数中
Sep 17 PHP
php访问数组最后一个元素的函数end()用法
Mar 18 PHP
PHP7新特性foreach 修改示例介绍
Aug 26 PHP
PHP的Json中文处理解决方案
Sep 29 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
Oct 18 PHP
PHPMailer使用QQ邮箱实现邮件发送功能
Aug 18 PHP
浅谈PHP之ThinkPHP框架使用详解
Jul 21 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 5.3.0 安装分析心得
2009/08/07 PHP
PHP GD库生成图像的几个函数总结
2014/11/19 PHP
php脚本守护进程原理与实现方法详解
2017/07/20 PHP
使用php自动备份数据库表的实现方法
2017/07/28 PHP
AJAX使用了UpdatePanel后无法使用alert弹出脚本
2010/04/02 Javascript
基于jQuery的实现简单的分页控件
2010/10/10 Javascript
Wordpress ThickBox 添加“查看原图”效果代码
2010/12/11 Javascript
jquery将一个表单序列化为一个对象的方法
2013/12/02 Javascript
js实现倒计时时钟的示例代码
2013/12/17 Javascript
Javascript 实现图片无缝滚动
2014/12/19 Javascript
jQuery支持动态参数将函数绑定到事件上的方法
2015/03/17 Javascript
JQuery中Ajax()的data参数类型实例分析
2015/12/15 Javascript
webpack配置的最佳实践分享
2017/04/21 Javascript
vue.js实现备忘录功能的方法
2017/07/10 Javascript
利用canvas中toDataURL()将图片转为dataURL(base64)的方法详解
2017/11/20 Javascript
Vue.js实现图片的随意拖动方法
2018/03/08 Javascript
centos 上快速搭建ghost博客方法分享
2018/05/23 Javascript
浅谈vue父子组件怎么传值
2018/07/21 Javascript
ES6 Object方法扩展的应用实例分析
2019/06/25 Javascript
swiper Scrollbar滚动条组件详解
2019/09/08 Javascript
python操作mongodb根据_id查询数据的实现方法
2015/05/20 Python
python基于twisted框架编写简单聊天室
2018/01/02 Python
替换python字典中的key值方法
2018/07/06 Python
python文件操作之批量修改文件后缀名的方法
2018/08/10 Python
python抓取京东小米8手机配置信息
2018/11/13 Python
Python matplotlib的使用并自定义colormap的方法
2018/12/13 Python
python实现超市商品销售管理系统
2019/11/22 Python
tensorflow的计算图总结
2020/01/12 Python
tensorflow 获取checkpoint中的变量列表实例
2020/02/11 Python
paramiko使用tail实时获取服务器的日志输出详解
2020/12/06 Python
iRobot官网:改变生活的家用机器人品牌
2016/09/20 全球购物
购买澳大利亚最好的服装和内衣在线:BONDS
2016/10/14 全球购物
小学家长学校培训材料
2014/08/24 职场文书
2014年城管工作总结
2014/11/20 职场文书
Python 类,对象,数据分类,函数参数传递详解
2021/09/25 Python
Vue全局事件总线你了解吗
2022/02/24 Vue.js