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 code
h1 h2
h3 h4
h5 h6
body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child
a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6
h1+p, h2+p, h3+p, h4+p, h5+p, h6+p
a a:hover
ul, ol
ul li>:first-child, ol li>:first-child, ul li ul:first-of-type, ol li ol:first-of-type, ul li ol:first-of-type, ol li ul:first-of-type
ul ul, ul ol, ol ol, ol ul
dl dl dt
dl dt:first-child
dl dt>:first-child
dl dt>:last-child
dl dd
dl dd>:first-child
dl dd>:last-child
pre, code, tt
code, tt
pre>code
pre
pre code, pre tt
kbd
blockquote
blockquote>:first-child
blockquote>:last-child
hr table th
table th, table td
table tr
table tr:nth-child(2n)
img
我們都知道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多程序
我們都知道php是單程序執行的,php處理多併發主要是依賴伺服器或php fpm的多程序及它們程序的復用,但php實現多程序也意義重大,尤其是在後台cli模式下處理大量資料或執行後台demon守護程序時,多程序的優勢不用多說。php的多執行緒也曾被人提及,但程序內多執行緒資源共享和分配的問題難以解決...
PHP多程序(1)PHP多程序初探
近日在開發過程 現了乙個奇葩問題。在我使用 php子程序處理發郵件的時候,在隔天再次1觸發相關 流程時,會把昨天的資料從使用子程序後再次重新處理一遍。導致資料出現重複,引發髒資料。為此,優化了 並且重新梳理了一下關於php多程序的問題。實際上php是有多程序的,有一些人在用,總體來說php的多程序還...