初探PHP多程序

2021-09-25 13:12:40 字數 2777 閱讀 1653

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

php的多執行緒也曾被人提及,但程序內多執行緒資源共享和分配的問題難以解決。php也有多執行緒想關的擴充套件 pthreads ,但據說不太穩定,且要求環境為執行緒安全,所用不多。

以前php群裡的一位大神曾指導說後台php想高階必然避不開多程序,正好公司裡的守護程序也應用了php的多程序,結合著谷哥的各種資料和手冊,總算理解了多程序,並自己寫了乙個小demo(在linux系統上實現的),用此文總結一下,如有錯漏,謝謝提出。

要實現php的多程序,我們需要兩個擴充套件 pcntl和 posix,安裝方法這裡不再贅述。

建立php子程序是多程序的開始,我們需要pcntl_fork()函式;

pcntl_fork() — 在當前程序當前位置產生分支(子程序)。此函式建立了乙個新的子程序後,子程序會繼承父程序當前的上下文,和父程序一樣從pcntl_fork()函式處繼續向下執行,只是獲取到的pcntl_fork()的返回值不同,我們便能從判斷返回值來區分父程序和子程序,分配父程序和子程序去做不同的邏輯處理。

pcntl_fork()函式成功執行時會在父程序返回子程序的程序id(pid),因為系統的初始程序init程序的pid為1,後來產生程序的pid都會大於此程序,所以我們可以通過判斷pcntl_fork()的返回值大於1來確實當前程序是父程序;

而在子程序中,此函式的返回值會是固定值0,我們也可以通過判斷pcntl_fork()的返回值為0來確定子程序;

而pcntl_fork()函式在執行失敗時,會在父程序返回-1,當然也不會有子程序產生。

以下是fork子程序的乙個簡單的小例子:

$ppid = posix_getpid();

$pid = pcntl_fork();

if ($pid == -1) elseif ($pid > 0) .");

sleep(30); // 保持30秒,確保能被ps查到

} else 的子程序,我的程序id是.");

sleep(30);

}

這時介紹一下兩個函式:

posix_getpid():獲取當前程序的pid;

cli_set_process_title('響亮的名字'):為當前程序取乙個響亮的名字。

執行這個例子,我們便能看到當前兩個php程序了。 

建立好了程序,那麼怎麼對子程序進行管理呢?使用訊號。

在電腦科學中,訊號是unix、類unix以及其他posix相容的作業系統中程序間通訊的一種有限制的方式。它是一種非同步的通知機制,用來提醒程序乙個事件已經發生。

我們通過在父程序接收子程序傳來的訊號,判斷子程序狀態,來對子程序進行管理。

我們需要在父程序裡使用pcntl_signal()函式和pcntl_signal_dispatch()函式來給各個子程序安裝訊號處理器。

pcntl_signal (int $signo , callback $handler) 安裝乙個訊號處理器;

$signo是待處理的訊號常量,callback是其處理函式

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

php內常見的訊號常量有:

sigchld     子程序退出成為殭屍程序會向父程序傳送此訊號

sighup 程序掛起

sigtem 程序終止

... // 其他請在手冊中檢視

安裝並呼叫訊號處理器後,一旦子程序有相應的訊號返回給父程序,父程序就可以呼叫相應的callback函式對子程序處理;

對子程序的處理方法有:

posix_kill():此函式並不能顧名思義,它通過向子程序傳送乙個訊號來操作子程序,在需要要時可以選擇給子程序傳送程序終止訊號來終止子程序;

pcntl_waitpid():等待或返回fork的子程序狀態,如果指定的子程序在此函式呼叫時已經退出(俗稱殭屍程序),此函式將立刻返回,並釋放子程序的所有系統資源,此程序可以避免子程序變成殭屍程序,造成系統資源浪費;

下面是兩個函式的函式原型:

bool posix_kill ( int $pid , int $sig ) // 向程序id為$pid的程序傳送$sig訊號,$sig常見訊號如上;

int pcntl_waitpid ( int $pid , int &$status [, int $options = 0 ] ) // 掛起當前程序的執行直到程序號為$pid的程序退出(如果$pid為-1,則等待任意乙個子程序);

這就是php多程序的基礎使用了,感興趣的可以自己寫乙個demo試一試手了。

最後貼一下鳥哥所說的php多程序優點:

使用多程序, 子程序結束以後, 核心會負責**資源

使用多程序,子程序異常退出不會導致整個程序thread退出. 父程序還有機會重建流程.

乙個常駐主程序, 只負責任務分發, 邏輯更清楚.

初探PHP多程序

我們都知道php是單程序執行的,php處理多併發主要是依賴伺服器或php fpm的多程序及它們程序的復用,但php實現多程序也意義重大,尤其是在後台cli模式下處理大量資料或執行後台demon守護程序時,多程序的優勢不用多說。php的多執行緒也曾被人提及,但程序內多執行緒資源共享和分配的問題難以解決...

初探PHP多程序

body blog calendar p,blockquote,ul,ol,dl,table,pre h1,h2,h3,h4,h5,h6 h1 tt,h1 code,h2 tt,h2 code,h3 tt,h3 code,h4 tt,h4 code,h5 tt,h5 code,h6 tt,h6 co...

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

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