PHP多程序初步

2022-06-23 04:39:09 字數 2654 閱讀 8949

我們都知道php是單執行緒執行,處理多併發主要是依賴伺服器或php-fpm的多程序及它們程序的復用,但php實現多程序也意義重大,尤其是在後台cli模式下處理大量資料或執行後台demon守護程序時。不能應用在web伺服器環境。

/*

* 檢測是否cli模式,確保這個函式只能執行在shell中

*/if (substr(php_sapi_name(), 0, 3) !== 'cli')

日常任務中,有時需要通過php指令碼執行一些日誌分析,佇列處理等任務,當資料量比較大時,可以使用多程序來處理。

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() 函式來給各個子程序安裝訊號處理器:

//

安裝乙個訊號處理器,$signo是待處理的訊號常量,callback是其處理函式

pcntl_signal (int $signo , callback

$handler

) //

呼叫每個等待訊號通過pcntl_signal()安裝的處理器

pcntl_signal_dispatch ()

php內常見的訊號常量有:

處理子程序,需要兩個函式:

//

向程序id為$pid的程序傳送$sig訊號

bool posix_kill ( int $pid, int $sig)//

掛起當前程序的執行直到程序號為$pid的程序退出(如果$pid為-1,則等待任意乙個子程序)

int pcntl_waitpid ( int $pid, int &$status [, int $options = 0 ] )

posix_kill() 函式通過向子程序傳送乙個訊號來操作子程序,在需要要時可以選擇給子程序傳送程序終止訊號來終止子程序;

pcntl_waitpid() 函式等待或返回 fork 的子程序狀態,如果指定的子程序在此函式呼叫時已經退出(俗稱殭屍程序),此函式將立刻返回,並釋放子程序的所有系統資源,此程序可以避免子程序變成殭屍程序,造成系統資源浪費。這樣就可以實現跟子程序共同完成的任務的目的了。

如果乙個任務被分解成多個程序執行,就會減少整體的耗時。比如有乙個比較大的資料檔案要處理,這個檔案由很多行組成。如果單程序執行要處理的任務,量很大時要耗時比較久。這時可以考慮多程序。多程序處理分解任務,每個程序處理檔案的一部分,這樣需要均分割一下這個大檔案成多個小檔案(程序數和小檔案的個數等同就可以)。

比如檔案 file.log 有10萬行資料,現在想分4個程序處理。需要分割2.5萬行乙個檔案。命令 split 可以做到:

<?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多程序》:

《php利用多程序處理任務》:

python 初步認識多程序

多程序程式是乙個指令的集合 程序 正在執行的程式,當你執行程式時,你就啟動了乙個程序 編寫完的 沒有執行時,稱為程式,正在執行的 稱為程序 多程序中每個程序的所有資料報括全域性變數都各擁有乙份,互不影響 程式開始執行時,首先會建立乙個主程序 在主程序下可以建立新的子程序,子程序依賴於主程序,如果主程...

PHP多程序 4 內部多程序

說的都是只相容unix 伺服器的多程序,下面來講講在window 和 unix 都相容的多程序 這裡是泛指,下面的curl實際上是通過io復用實現的 通過擴充套件實現多執行緒的典型例子是curl,curl 支援多執行緒的抓取網頁的功能。這部分過於抽象,所以,我先給出乙個curl並行抓取多個網頁內容的...

PHP多程序 四 內部多程序

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