摘要:普通請求創(chuàng)建多個資源并發(fā)創(chuàng)建多個資源創(chuàng)建批處理句柄增加句柄待優(yōu)化點在執(zhí)行而整個批處理句柄沒有全部執(zhí)行完畢時,系統(tǒng)會不停地執(zhí)行函數(shù)。進(jìn)行改動的方式是應(yīng)用函數(shù)庫中的函數(shù),其函數(shù)原型如下阻塞直到批處理連接中有活動連接。
普通請求
curl_normal.php
use time:0.830 s
curl_multi并發(fā)curl_multi.php
$ch){ curl_multi_add_handle($mh, $ch); //2 增加句柄 } $active = null; //待優(yōu)化點: //在$active > 0,執(zhí)行curl_multi_exec($mh,$active)而整個批處理句柄沒有全部執(zhí)行完畢時,系統(tǒng)會不停地執(zhí)行curl_multi_exec()函數(shù)。 do{ echo "running "; curl_multi_exec($mh, $active); //3 執(zhí)行批處理句柄 }while($active > 0); //4 foreach($chArr as $k => $ch){ $result[$k]= curl_multi_getcontent($ch); //5 獲取句柄的返回值 curl_multi_remove_handle($mh, $ch);//6 將$mh中的句柄移除 } curl_multi_close($mh); //7 關(guān)閉全部句柄 // print_r($result); $end_time = microtime(TRUE); echo sprintf("use time:%.3f s", $end_time - $srart_time); ?>
use time:0.259 s
curl_multi并發(fā)優(yōu)化:curl_multi_select在上個示例里當(dāng)$active > 0時,執(zhí)行curl_multi_exec($mh,$active)而整個批處理句柄沒有全部執(zhí)行完畢時,系統(tǒng)會不停地執(zhí)行curl_multi_exec()函數(shù)。這樣可能會輕易導(dǎo)致CPU占用很高。
進(jìn)行改動的方式是應(yīng)用curl函數(shù)庫中的curl_multi_select()函數(shù),其函數(shù)原型如下:
int curl_multi_select ( resource $mh [, float $timeout = 1.0 ] )
阻塞直到cURL批處理連接中有活動連接。成功時返回描述符集合中描述符的數(shù)量。失敗時,select失敗時返回-1,否則返回超時(從底層的select系統(tǒng)調(diào)用)。
我用們curl_multi_select()函數(shù)來達(dá)到?jīng)]有需要讀取的程序就阻塞住的目的。
下面是優(yōu)化部分的代碼:
curl_multi_select.php
$active = null; do{ echo "running "; $mrc = curl_multi_exec($mh, $active); //3 執(zhí)行批處理句柄 }while ($mrc == CURLM_CALL_MULTI_PERFORM); //4 //本次循環(huán)第一次處理$mh批處理中的$ch句柄,并將$mh批處理的執(zhí)行狀態(tài)寫入$active ,當(dāng)狀態(tài)值等于CURLM_CALL_MULTI_PERFORM時,表明數(shù)據(jù)還在寫入或讀取中,執(zhí)行循環(huán),當(dāng)?shù)谝淮?ch句柄的數(shù)據(jù)寫入或讀取成功后,狀態(tài)值變?yōu)镃URLM_OK,跳出本次循環(huán),進(jìn)入下面的大循環(huán)之中。 //$active 為true,即$mh批處理之中還有$ch句柄正待處理,$mrc==CURLM_OK,即上一次$ch句柄的讀取或?qū)懭胍呀?jīng)執(zhí)行完畢。 while ($active && $mrc == CURLM_OK) { if (curl_multi_select($mh) != -1) {//$mh批處理中還有可執(zhí)行的$ch句柄,curl_multi_select($mh) != -1程序退出阻塞狀態(tài)。 do { $mrc = curl_multi_exec($mh, $active);//繼續(xù)執(zhí)行需要處理的$ch句柄。 } while ($mrc == CURLM_CALL_MULTI_PERFORM); } }
這樣執(zhí)行的好處是$mh批處理中的$ch句柄會在讀取或?qū)懭霐?shù)據(jù)結(jié)束后($mrc==CURLM_OK),進(jìn)入curl_multi_select($mh)的阻塞階段,而不會在整個$mh批處理執(zhí)行時不停地執(zhí)行curl_multi_exec,白白浪費CPU資源。
運行結(jié)果:
use time:0.325 s
耗時并沒有多少改變,只是性能提高了。
curl_multi并發(fā)優(yōu)化:rolling上面的例子還存在優(yōu)化的空間, 優(yōu)化的方式時當(dāng)某個URL請求完畢之后盡可能快的去處理它, 邊處理邊等待其他的URL返回, 而不是等待那個最慢的接口返回之后才開始處理等工作, 從而避免CPU的空閑和浪費。
僅貼出修改部分:
curl_multi_rolling.php
$active = null; do { while (($mrc = curl_multi_exec($mh, $active)) == CURLM_CALL_MULTI_PERFORM) ; if ($mrc != CURLM_OK) { break; } // a request was just completed -- find out which one while ($done = curl_multi_info_read($mh)) { // get the info and content returned on the request $info = curl_getinfo($done["handle"]); $error = curl_error($done["handle"]); $result[] = curl_multi_getcontent($done["handle"]); // $responses[$map[(string) $done["handle"]]] = compact("info", "error", "results"); // remove the curl handle that just completed curl_multi_remove_handle($mh, $done["handle"]); curl_close($done["handle"]); } // Block for data in / output; error handling is done by curl_multi_exec if ($active > 0) { curl_multi_select($mh); } } while ($active);
use time:0.267 s
參考1、PHP模擬發(fā)送POST請求之五curl基本使用和多線程優(yōu)化
http://www.cnblogs.com/zhenbi...
2、Rolling cURL: PHP并發(fā)最佳實踐
https://www.oschina.net/quest...
3、curl_multi_select解決curl_multi網(wǎng)頁假死問題
http://www.webkaka.com/tutori...
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/28656.html
摘要:根據(jù)獲取請求對象這個比較簡單可以看官方文檔將三個待請求對象放入下載器中輪詢一旦有一個請求完成,找出來,處理因為底層是,所以最大受限于從請求中獲取信息內(nèi)容錯誤把請求已經(jīng)完成了得刪除當(dāng)沒有數(shù)據(jù)的時候進(jìn)行堵塞,把使用權(quán)交出來,避免上面死循環(huán)空跑數(shù) class CurlMultiUtil { /** * 根據(jù)url,postData獲取curl請求對象,這個比較簡單,可以看官方...
摘要:不支持多線程模式和回調(diào)處理,因此內(nèi)部腳本都是同步阻塞式的,如果你發(fā)起一個的請求,那么程序就會阻塞,直到請求返回結(jié)果,才會繼續(xù)執(zhí)行代碼。參考資料手冊手冊預(yù)定義常量中實現(xiàn)多線程請求詳解每次使用同時并發(fā)多少請求合適簡書多線程及原理 后端服務(wù)開發(fā)中經(jīng)常會有并發(fā)請求的需求,比如你需要獲取10家供應(yīng)商的帶寬數(shù)據(jù)(每個都提供不同的url),然后返回一個整合后的數(shù)據(jù),你會怎么做呢? 在PHP中,最直觀...
摘要:今天我就來聊聊我關(guān)于函數(shù)集的使用心得,關(guān)于請求的問題。耗時這是不能容忍的。事實上內(nèi)部實現(xiàn)就是用的事件循環(huán)。通過函數(shù)創(chuàng)建下載器。四復(fù)雜的運用這就是用法在上面的例子中。動態(tài)的從下載器中取出已經(jīng)完成了的請求。函數(shù)實現(xiàn)的壓測工具。 一、引言 這段時間比較忙,已經(jīng)很久沒有寫博客了。今天我就來聊聊我關(guān)于curl_multi_*函數(shù)集的使用心得,關(guān)于http請求的問題。 當(dāng)我們用戶php發(fā)起一個ht...
摘要:最近在維護(hù)一個三年前的舊代碼,用的是框架。單元測試和語言并發(fā)控制實際上是個蛋疼的問題,夸張一點說,當(dāng)時的并不能特別輕松地實現(xiàn)并發(fā),甚至不能實現(xiàn)并發(fā)。語言的功能之一就是自帶單元測試。用語言之前,我的習(xí)慣是不寫單元測試。 最近在維護(hù)一個三年前的舊代碼,用的是laravel框架。 從某些方面來講,這個代碼算是比較標(biāo)準(zhǔn)為了實現(xiàn)在規(guī)定的時間內(nèi)完成相關(guān)功能,同時程序員水平不高、經(jīng)過大量優(yōu)化之后,變...
摘要:編程中的并發(fā)周末去北京面了兩個公司,認(rèn)識了幾位技術(shù)牛人,面試中聊了很多,感覺收獲頗豐。本文大約總結(jié)了編程中的五種并發(fā)方式,最后的的實現(xiàn)純屬無聊,可以無視。生成的可以中斷函數(shù),并用向發(fā)送消息。 PHP編程中的并發(fā) 周末去北京面了兩個公司,認(rèn)識了幾位技術(shù)牛人,面試中聊了很多,感覺收獲頗豐。認(rèn)識到了自己的不足之處,也堅定了自己對計算機(jī)學(xué)習(xí)的信心。本文是對其中一道面試題的總結(jié)。 面試中有一個問...
閱讀 2596·2021-11-22 12:01
閱讀 1121·2021-11-15 11:37
閱讀 3709·2021-09-22 14:59
閱讀 1769·2021-09-04 16:45
閱讀 1400·2021-09-03 10:30
閱讀 1035·2021-08-11 11:18
閱讀 2476·2019-08-30 10:53
閱讀 2028·2019-08-29 15:13