最近工作需要,需要为商户发送weixin的消息模板,而消息模板是通过curl请求的http api,单进程发送太慢,多开脚本又无法系统化、脚本数量无法精确化,系统资源占用高,于是想起采用多线程。
看了张宴的博客,很不错,原文地址:http://zyan.cc/pthreads/
pthread的安装就不赘述了,下载进行动态加载或者静态编译均可: http://php.net/manual/zh/book.pthreads.php
下面是我测试的脚本:
<?php
class TestThread extends Thread
{
public $url ;
public $data ;
public function __construct($url)
{
$this->url = $url ;
}
public function run()
{
$this->data = curlGet($this->url) ;
}
}
function curlGet($url)
{
// 创建一个新cURL资源
$ch = curl_init();
// 设置URL和相应的选项
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_TIMEOUT, 5) ;
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1) ;
// 抓取URL并把它传递给浏览器
$data = curl_exec($ch);
// 关闭cURL资源,并且释放系统资源
curl_close($ch);
return $data ;
}
function createThread($urlArray)
{
//create thread
foreach ($urlArray as $i=>$url) {
$threadArray[$i] = new TestThread($url) ;
$threadArray[$i]->start() ;
}
foreach ($threadArray as $key => $thread) {
while($thread->isRunning()){
usleep(10) ;
}
if($thread->join()){
$threadDataArray[$key] = $thread->data."==".$key."\n" ;
}
}
return $threadDataArray ;
}
for($i=0; $i<100; $i++){
$url = 'http://baidu.com' ;
$urlArray[] = $url ;
}
$t = microtime(true);
$data = createThread($urlArray);
$e = microtime(true);
echo "多线程:".($e-$t)."\n";
$t = microtime(true);
for($j=0; $j<20; $j++){
$tmpUrlArray = array_slice($urlArray,0,5) ;
$data = createThread($tmpUrlArray);
}
$e = microtime(true);
echo "多线程2:".($e-$t)."\n";
$t = microtime(true);
foreach ($urlArray as $key => $value)
{
$result_new[$key] = curlGet($value);
}
$e = microtime(true);
echo "For循环:".($e-$t)."\n";
?>
测试环境:Dell 2950 2GRAM
测试结果:
多线程:0.44615602493286
多线程2:0.50709319114685
For循环:1.3469228744507
线程太多不仅瞬间占用CPU和内存过高,耗时最小;单进程curl明显是耗时最长的;第二种多线程则是在资源占用和耗时上趋于中间的,所以在实际的线上环境明显要采用这种的。