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 相关文章推荐
拼音码表的生成
Oct 09 PHP
坏狼的PHP学习教程之第1天
Jun 15 PHP
php file_get_contents函数轻松采集html数据
Apr 22 PHP
在php中判断一个请求是ajax请求还是普通请求的方法
Jun 28 PHP
PHP之短标签开启设置
Jun 17 PHP
php制作unicode解码工具(unicode编码转换器)代码分享
Dec 24 PHP
PHP文件上传判断file是否己选择上传文件的方法
Nov 10 PHP
PHP+Ajax实现无刷新分页实例详解(附demo源码下载)
Apr 07 PHP
PHP中字符串长度的截取用法示例
Jan 12 PHP
php根据命令行参数生成配置文件详解
Mar 15 PHP
Laravel5.7 Eloquent ORM快速入门详解
Apr 12 PHP
THINKPHP-Apache服务器中使用Alias虚拟目录URL重写 隐藏index.php
Mar 09 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 函数语法介绍一
2009/06/14 PHP
PHP无敌近乎加密方式!
2010/07/17 PHP
PHP连接SQLSERVER 注意事项(附dll文件下载)
2012/06/28 PHP
php实现根据IP地址获取其所在省市的方法
2015/04/30 PHP
php 中htmlentities导致中文无法查询问题
2018/09/10 PHP
JavaScript中令你抓狂的魔术变量
2006/11/30 Javascript
jQuery对下拉框,单选框,多选框的操作
2014/02/21 Javascript
Javascript连接多个数组不用concat来解决
2014/03/24 Javascript
JScript中的条件注释详解
2015/04/24 Javascript
javascript实现数字倒计时特效
2016/03/30 Javascript
Angularjs中的事件广播 —全面解析$broadcast,$emit,$on
2016/05/17 Javascript
jQuery each函数源码分析
2016/05/25 Javascript
jQuery实现产品对比功能附源码下载
2016/08/09 Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
2017/03/30 Javascript
详解webpack 入门总结和实践(按需异步加载,css单独打包,生成多个入口文件)
2017/06/20 Javascript
JavaScript对象_动力节点Java学院整理
2017/06/23 Javascript
React native ListView 增加顶部下拉刷新和底下点击刷新示例
2018/04/27 Javascript
深入学习JavaScript中的bom
2019/05/27 Javascript
JS倒计时两种实现方式代码实例
2020/07/27 Javascript
Vue实现腾讯云点播视频上传功能的实现代码
2020/08/17 Javascript
详解vue中使用transition和animation的实例代码
2020/12/12 Vue.js
Python使用pylab库实现画线功能的方法详解
2017/06/08 Python
使用python实现tcp自动重连
2017/07/02 Python
Python 模拟登陆的两种实现方法
2017/08/10 Python
详解python中@的用法
2019/03/27 Python
处理python中多线程与多进程中的数据共享问题
2019/07/28 Python
关于Keras Dense层整理
2020/05/21 Python
Pytorch 解决自定义子Module .cuda() tensor失败的问题
2020/06/23 Python
python基于爬虫+django,打造个性化API接口
2021/01/21 Python
JSF面试题:Jsf中的核心类用那些?有什么作用?LiftCycle六大生命周期是什么?
2014/07/17 面试题
酒店开业庆典策划方案
2014/05/28 职场文书
市场营销专业应届生自荐信
2014/06/19 职场文书
师德先进个人事迹材料
2014/12/19 职场文书
医院见习总结
2015/06/24 职场文书
乡镇司法所2015年度工作总结
2015/10/14 职场文书
Python中生成随机数据安全性、多功能性、用途和速度方面进行比较
2022/04/14 Python