这篇文章主要介绍了服务器端编程语言(专业超文本预处理器的缩写)使用curl_init()和curl_multi_init()多线程的速度比较,结合实例形式详细分析了curl_init()和curl_multi_init()的具体使用方法及相关效率比较,需要的朋友可以参考下
本文实例讲述了服务器端编程语言(专业超文本预处理器的缩写)使用curl_init()和curl_multi_init()多线程的速度比较。分享给大家供大家参考,具体如下:
服务器端编程语言(专业超文本预处理器的缩写)中curl_init()的作用很大,尤其是在抓取网页内容或文件信息的时候,例如之前文章《php使用curl获取header检测开启GZip压缩》 就介绍到curl_init()的强大。
curl_init()处理事物是单线程模式,如果需要对事务处理走多线程模式,那么服务器端编程语言(专业超文本预处理器的缩写)里提供了一个函数curl_multi_init()给我们,这就是多线程模式处理事务的函数。
curl_init()与curl_multi_init()的速度比较curl_multi_init()多线程能提高网页的处理速度吗?今天我通过实验来验证一下这个问题。
今天我的测试很简单,那就是要抓取www.webkaka.com网页的内容,要连续抓5次,分别用curl_init()和curl_multi_init()函数来完成,记录两者的耗时,比较得出结论。
首先,用curl_init()单线程连续抓5次www.webkaka.com网页的内容。
程序代码如下:
?服务器端编程语言(专业超文本预处理器的缩写)
$mtime=explode( ,microtime());
$mtime=$mtime[1].($ mtime[0]* 1000);
$mtime2=explode( . ,$ mtime);
$ mtime=$ mtime 2[0];
echo $ mtime
回声报
for($ I=1;$ I=5;$i ){
$ szUrl=http://www.webkaka.com/;
$ curl=curl _ init();
curl_setopt($curl,CURLOPT_URL,$ szUrl);
curl_setopt($curl,CURLOPT_HEADER,0);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
curl_setopt($curl,CURLOPT_ENCODING, );
$ data=curl _ exec($ curl);
echo $ data
回声报
$mtime_=explode( ,microtime());
$mtime_=$mtime_[1].($ mtime _[0]* 1000);
$mtime2_=explode( . ,$ mtime _);
$ mtime _=$ mtime 2 _[0];
echo $ mtime _;
回声报
echo $ mtime _-$ mtime;
}
?
然后,用curl_multi_init()多线程连续抓5次www.webkaka.com网页的内容。
代码如下:
?服务器端编程语言(专业超文本预处理器的缩写)
echo date(Y-m-d H:m:s ,time());
回显"";
echo floor(microtime()* 1000);
回声报
$mtime=explode( ,microtime());
$mtime=$mtime[1].($ mtime[0]* 1000);
$mtime2=explode( . ,$ mtime);
$ mtime=$ mtime 2[0];
echo $ mtime
回声报
$urls=array(
http://www.webkaka.com,
http://www.webkaka.com,
http://www.webkaka.com,
http://www.webkaka.com,
http://www。web卡卡。com’);
print _ r(async _ get _ URL($ URLs));//[0]=示例1,[1]=示例2
回声报
echo date(Y-m-d H:m:s ,time());
回显"";
echo floor(microtime()* 1000);
回声报
$mtime_=explode( ,microtime());
$mtime_=$mtime_[1].($ mtime _[0]* 1000);
$mtime2_=explode( . ,$ mtime _);
$ mtime _=$ mtime 2 _[0];
echo $ mtime _;
回声报
echo $ mtime _-$ mtime;
函数async_get_url($url_array,$wait_usec=0)
{
如果(!is_array($url_array))
返回错误的
$ wait _ usec=intval($ wait _ usec);
$ data=array();
$ handle=array();
$ running=0;
$ MH=curl _ multi _ init();//多重卷曲处理程序
$ I=0;
foreach($url_array as $url) {
$ ch=curl _ init();
curl_setopt($ch,CURLOPT_URL,$ URL);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//返回不打印
curl_setopt($ch,CURLOPT_TIMEOUT,30);
curl_setopt($ch,CURLOPT_USERAGENT, Mozilla/4.0(兼容;MSIE 5.01 windows NT 5.0));
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);//302重定向
curl_setopt($ch,CURLOPT_MAXREDIRS,7);
curl_multi_add_handle($mh,$ ch);//把卷曲资源放进多卷曲处理器里
$ handle[$ I]=$ ch;
}
/* 执行*/
做{
curl_multi_exec($mh,$ running);
if ($wait_usec 0) /*每个连接要间隔多久*/
美国LEEP($ wait _ usec);//250000=0.25秒
} while($运行0);
/* 读取资料*/
foreach($handle as $i=$ch) {
$ content=curl _ multi _ get content($ ch);
$data[$i]=(curl_errno($ch)==0)?$ content:false;
}
/* 移除句柄*/
foreach($handle as $ch) {
curl_multi_remove_handle($mh,$ ch);
}
curl _ multi _ close($ MH);
返回$数据
}
?
为了避免随机性,我测了五次(用CTRL F5强行刷新),数据如下:
curl_init():
第一次
第二次
第三次
第四次
第五次
平均的
耗时(毫秒)
3724
3615
2540
1957
2794
2926
curl_multi_init():
第一次
第二次
第三次
第四次
第五次
平均的
耗时(毫秒)
4275
2912
3691
4198
3891
3793
从测试结果来看,我们发现两种方法的耗时相差不大,只有700多毫秒。许多人认为多线程会比单线程花费更少的时间,但事实并非如此。从数据来看,多线程比单线程多花一点时间。但是对于某些事务,多线程不一定是为了速度,这一点要注意。
关于curl_multi_init()一般来说,在考虑使用curl_multi_init()的时候,目的是同时请求多个url,而不是一个一个地请求,要不然就要用到curl_init()。
但在使用curl_multi时,可能会遇到cpu消耗过大、网页假死等现象。可以看《PHP使用curl_multi_select解决curl_multi网页假死问题》。
使用curl_multi的步骤总结如下:
步骤1:调用curl_multi_init
第二步:循环调用curl_multi_add_handle。
这一步需要注意的是,curl_multi_add_handle的第二个参数是从curl_init派生的子句柄。
第三步:连续调用curl_multi_exec。
第四步:根据需要循环调用curl_multi_getcontent得到结果。
第五步:为每个字句柄调用curl_multi_remove_handle和curl_close。
第六步:调用curl_multi_close
各函数作用解释:
curl_multi_init()
初始化curl批处理句柄资源。
curl_multi_add_handle()
向curl批处理会话添加一个单独的curl句柄资源。curl_multi_add_handle()函数有两个参数。第一个参数表示一个curl批处理句柄资源,第二个参数表示一个单独的curl句柄资源。
curl_multi_exec()
解析curl批处理句柄。curl_multi_exec()函数有两个参数。第一个参数指示批处理句柄资源,第二个参数是参考值参数,指示剩余待处理的单个curl句柄资源的数量。
curl_multi_remove_handle()
要从curl批处理句柄资源中移除一个句柄资源,curl_multi_remove_handle()函数有两个参数,第一个参数指示一个curl批处理句柄资源,第二个参数指示一个单独的curl句柄资源。
curl_multi_close()
关闭批处理句柄资源。
curl_multi_getcontent()
当CURLOPT_RETURNTRANSFER被设置时,返回所获得的输出的文本流。
curl_multi_info_read()
获取当前解析的curl的相关传输信息。
实例
请看本文中async_get_url()的写法。
更多对PHP相关内容感兴趣的读者,请参考我们的专题:《php curl用法总结》、《PHP网络编程技巧总结》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》和《PHP数据结构与算法教程》。
希望这篇文章对大家的PHP编程有所帮助。