PHP多程序 4 內部多程序

2021-09-08 18:28:16 字數 2863 閱讀 7905

說的都是只相容unix 伺服器的多程序,下面來講講在window 和 unix 都相容的多程序(這裡是泛指,下面的curl實際上是通過io復用實現的)。

通過擴充套件實現多執行緒的典型例子是curl,curl 支援多執行緒的抓取網頁的功能。

這部分過於抽象,所以,我先給出乙個curl並行抓取多個網頁內容的乙個分裝類。這個類實際上很實用,

詳細分析這些函式的內部實現將在下乙個教程裡面描述。

你可能不能很好的理解這個類,而且,php curl 官方主頁上都有很多錯誤的例子,在講述了其內部機制

後,你就能夠明白了。

先看**:

//設定url 列表

function seturls($urls)

//設定選項

function setoptions($options)

if (!isset($options[curlopt_useragent]))

if (!isset($options[curlopt_followlocation]))

if (!isset($options[curlopt_header]))

$this->options =$options;

}//並行抓取所有的內容

function exec()

$curl = $data =array();

$mh =curl_multi_init();

foreach($this->urls as $k =>$v)

$this->execmulithandle($mh);

foreach($this->urls as $k =>$v)

curl_multi_close($mh);

return

$data;

}//只抓取乙個網頁的內容。

function execone($url)

$ch =curl_init($url);

$this->setoneoption($ch);

$content =curl_exec($ch);

curl_close($ch);

return

$content;

}//內部函式,設定某個handle 的選項

private

function setoneoption($ch)

//新增乙個新的並行抓取 handle

private

function addhandle($mh, $url)

//並行執行(這樣的寫法是乙個常見的錯誤,我這裡還是採用這樣的寫法,這個寫法

//

//這是乙個典型的不懂原理產生的錯誤。這個錯誤在php官方的文件上都相當的常見。)

private

function execmulithandle2($mh)

while ($running > 0

);

//var_dump($i);}

//應該用這樣的寫法

private

function execmulithandle($mh)

while ($mrc ==curlm_call_multi_perform);

while ($active && $mrc ==curlm_ok)

while ($mrc ==curlm_call_multi_perform);

}$i++;

}//var_dump($i);

}}

看最後乙個注釋最多的函式,這個錯誤在平時除錯的時候可能不太容易發現,因為程式完全正常,但是,在生產伺服器下,馬上會引起崩潰效果。

解釋為什麼不能這樣,必須從c 語言內部實現的角度來分析。這個部分將放到下乙個教程(php高階程式設計之–單執行緒實現並行抓取網頁 )。不過不是通過c語言來表述原理,而是通過php

這個類,實際上也就很簡單的實現了前面我們費了4個教程的篇幅,並且是九牛二虎之力才實現的多執行緒的抓取網頁的功能。在純php的實現下,我們只能用乙個後台服務的方式來比較好的實現,但是當你使用 作業系統介面語言 c 語言時候,這個實現當然就更加的簡單,靈活,高效。

就同時抓取幾個網頁這樣一件簡單的事情,實際上在底層涉及到了很多東西,對很多半路出家的php程式設計師,可能不喜歡談多執行緒這個東西,深入了就涉及到作業系統,淺點說就是並行執行好幾個「程式」。但是,很多時候,多執行緒必不可少,比如要寫個快點的爬蟲,往往就會浪費九牛二虎之力。不過,php的程式設計師現在應該感謝curl 這個擴充套件,這樣,你完全不需要用你不太精通的 python 去寫爬蟲了,對於乙個中型大小的爬蟲,有這個內部多執行緒,就已經足夠了。

最後是上面的類的乙個測試的例子:

parallel fetch(並行抓取):

$data = $m->exec();

$parallel_time = microtime(true) -$t;

echo $parallel_time . "\n

";$t = microtime(true);

//serial fetch(序列抓取):

foreach ($urls as

$url)

$serial_time = microtime(true) -$t;

echo $serial_time . "\n

";

PHP多程序 四 內部多程序

上面乙個系列的教程 用 socket 和 pcntl 實現乙個多程序伺服器 一 php多程序程式設計 一 php多程序程式設計 二 管道通訊 php多程序程式設計 三 多程序抓取網頁的演示 說的都是只相容unix 伺服器的多程序,下面來講講在window 和 unix 都相容的多程序 這裡是泛指,下...

PHP多程序(1)PHP多程序初探

近日在開發過程 現了乙個奇葩問題。在我使用 php子程序處理發郵件的時候,在隔天再次1觸發相關 流程時,會把昨天的資料從使用子程序後再次重新處理一遍。導致資料出現重複,引發髒資料。為此,優化了 並且重新梳理了一下關於php多程序的問題。實際上php是有多程序的,有一些人在用,總體來說php的多程序還...

多程序 多程序queue

多程序 import multiprocessing import threading import time defthread run print threading.get ident defrun name time.sleep 2 print hello name t threading....