我們都知道php是單執行緒執行,處理多併發主要是依賴伺服器或php-fpm的多程序及它們程序的復用,但php實現多程序也意義重大,尤其是在後台cli模式下處理大量資料或執行後台demon守護程序時。不能應用在web伺服器環境。
/*日常任務中,有時需要通過php指令碼執行一些日誌分析,佇列處理等任務,當資料量比較大時,可以使用多程序來處理。* 檢測是否cli模式,確保這個函式只能執行在shell中
*/if (substr(php_sapi_name(), 0, 3) !== 'cli')
php的多執行緒也曾被人提及,但程序內多執行緒資源共享和分配的問題難以解決。php也有多執行緒想關的擴充套件 pthreads ,但據說不太穩定,且要求環境為執行緒安全,所用不多。
要實現php的多程序,需要安裝 pcntl 和 posix 擴充套件。
使用 pcntl_fork() 函式可以在當前位置產生分支。fork 是建立了乙個子程序,父程序和子程序都從 fork 的位置開始向下繼續執行,不同的是父程序執行過程中,得到的 fork 返回值為子程序號,而子程序得到的是0,執行失敗則返回-1。
因為系統初始init程序的pid為1,後來的所有程序pid都會大於該程序,所以可以通過 pcntl_fork() 的返回值大於1來判斷當前程序是父程序,返回值等於0來判斷是子程序。
$ppid = posix_getpid(); //執行結果:獲取當前程序的id
$pid = pcntl_fork(); //
建立子程序
if ($pid == -1)
elseif ($pid > 0) .");
sleep(30);
pcntl_wait(
$status); //
等待子程序中斷,防止子程序成為殭屍程序。
} else
的子程序,我的程序id是.");
sleep(30);
}
注意:如果是在迴圈中建立子程序,那麼子程序中最後要 exit 退出,防止子程序進入迴圈。
管理子程序,使用的是訊號。簡單來說,就是父程序裡使用兩個函式 pcntl_signal() 和 pcntl_signal_dispatch(),負責給子程序安裝訊號處理器和分發工作。
在電腦科學中,訊號是unix、類unix以及其他posix相容的作業系統中程序間通訊的一種有限制的方式。它是一種非同步的通知機制,用來提醒程序乙個事件已經發生。我們通過在父程序接收子程序傳來的訊號,判斷子程序狀態,來對子程序進行管理。我們需要在父程序裡使用 pcntl_signal() 函式和 pcntl_signal_dispatch() 函式來給各個子程序安裝訊號處理器:
//php內常見的訊號常量有:安裝乙個訊號處理器,$signo是待處理的訊號常量,callback是其處理函式
pcntl_signal (int $signo , callback
$handler
) //
呼叫每個等待訊號通過pcntl_signal()安裝的處理器
pcntl_signal_dispatch ()
處理子程序,需要兩個函式:
//posix_kill() 函式通過向子程序傳送乙個訊號來操作子程序,在需要要時可以選擇給子程序傳送程序終止訊號來終止子程序;向程序id為$pid的程序傳送$sig訊號
bool posix_kill ( int $pid, int $sig)//
掛起當前程序的執行直到程序號為$pid的程序退出(如果$pid為-1,則等待任意乙個子程序)
int pcntl_waitpid ( int $pid, int &$status [, int $options = 0 ] )
pcntl_waitpid() 函式等待或返回 fork 的子程序狀態,如果指定的子程序在此函式呼叫時已經退出(俗稱殭屍程序),此函式將立刻返回,並釋放子程序的所有系統資源,此程序可以避免子程序變成殭屍程序,造成系統資源浪費。這樣就可以實現跟子程序共同完成的任務的目的了。
如果乙個任務被分解成多個程序執行,就會減少整體的耗時。比如有乙個比較大的資料檔案要處理,這個檔案由很多行組成。如果單程序執行要處理的任務,量很大時要耗時比較久。這時可以考慮多程序。多程序處理分解任務,每個程序處理檔案的一部分,這樣需要均分割一下這個大檔案成多個小檔案(程序數和小檔案的個數等同就可以)。
比如檔案 file.log 有10萬行資料,現在想分4個程序處理。需要分割2.5萬行乙個檔案。命令 split 可以做到:
<?php參考:《php多程序總結》:shell_exec('split -l 25000 -d file.log prefix_name');
//3個子程序處理任務
for ($i = 0; $i
< 3; $i++)
elseif ($pid
) else }//
等待子程序執行結束
while (pcntl_waitpid(0, $status) != -1)
《初探php多程序》:
《php利用多程序處理任務》:
python 初步認識多程序
多程序程式是乙個指令的集合 程序 正在執行的程式,當你執行程式時,你就啟動了乙個程序 編寫完的 沒有執行時,稱為程式,正在執行的 稱為程序 多程序中每個程序的所有資料報括全域性變數都各擁有乙份,互不影響 程式開始執行時,首先會建立乙個主程序 在主程序下可以建立新的子程序,子程序依賴於主程序,如果主程...
PHP多程序 4 內部多程序
說的都是只相容unix 伺服器的多程序,下面來講講在window 和 unix 都相容的多程序 這裡是泛指,下面的curl實際上是通過io復用實現的 通過擴充套件實現多執行緒的典型例子是curl,curl 支援多執行緒的抓取網頁的功能。這部分過於抽象,所以,我先給出乙個curl並行抓取多個網頁內容的...
PHP多程序 四 內部多程序
上面乙個系列的教程 用 socket 和 pcntl 實現乙個多程序伺服器 一 php多程序程式設計 一 php多程序程式設計 二 管道通訊 php多程序程式設計 三 多程序抓取網頁的演示 說的都是只相容unix 伺服器的多程序,下面來講講在window 和 unix 都相容的多程序 這裡是泛指,下...