前提:眾所周知,php都是單程序處理的,處理多併發呢主要是依賴php-fpm多程序,以及他們程序的復用。但是我們使用php多程序也是很有意義的,特別是在cli模式下處理大資料,或者執行後台demon守護程序時,多程序的優勢不用多說。
主要用到pcntl的擴充套件以及相關方法函式。
我為什麼用到了多程序:
公司專案中,有乙個業務類似定時任務去第三方拉取資料,然後修改自己的業務。一般這種需求第一首先想到的就是crontab,直接走定時任務。沒錯,最開始我也是這樣想的,但是我後來想了一下,定時任務定多長時間執行一次呢,短了的話 可能會造成資料重複處理,雖然有補救錯誤不影響業務,但是處理重複資料是沒有任何意義的。所以最初我的想法是後台nohup守護程序,然後**裡面是無限遞迴的方式,這樣的話可以避免資料重複處理,也能實現實時性。但是緊接著另外乙個問題出來了。因為**裡面是無限遞迴的方式,你宣告的變數加上從第三方拉取的資料都會占用記憶體,隨著時間的推移,你的**占用的記憶體會越來越大,最終超過了ini中的閥值,就會殺死程序,php在**記憶體方面比較薄弱。我最開始也看了鳥哥的部落格,誰動了我的記憶體那篇文章,了解了php記憶體是怎麼回事。事實也能證明,你及時的unset掉變數,記憶體也會**。但是**何其長,變數何其多,這樣的話 在**中要加很多的unset,不但**不美觀,質量也下降了很多,無奈之舉我接觸到了php多程序。
我是怎麼用php多程序來處理這個業務的:
首先我們要對php多程序的概念熟悉一下
建立php子程序是多程序的開始,我們需要pcntl_fork()函式;
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,當然也不會有子程序產生。
我們建立了子程序去處理資料業務,我們還得知道什麼時候子程序結束,然後建立下乙個子程序繼續處理。這裡我們會用到另外乙個函式pcntl_waitpid();
pcntl_waitpid函式詳解:
掛起當前程序的執行直到引數pid指定的程序號的程序退出, 或接收到乙個訊號要求中斷當前程序或呼叫乙個訊號處理函式。
如果pid指定的子程序在此函式呼叫時已經退出(俗稱殭屍程序),此函式 將立刻返回
返回值:
pcntl_waitpid()返回退出的子程序程序號,發生錯誤時返回-1,如果提供了 wnohang作為option(wait3可用的系統)並且沒有可用子程序時返回0。
我們可以根據返回值來判斷子程序是否出來完畢,然後繼續建立程序來處理。
說了這麼多 貼下我自己的**demo
使用這種方法處理大資料很適用,類似mapreduce。當然了我這種是乙個子程序完了之後才會建立另外乙個程序。如果大家要一下子建立多個子程序的話,需要對子程序管理就會用到訊號的概念,稍微複雜,有興趣的可以google。
PHP多程序簡單例項小結
php建立多程序需要使用到pcntl模組 在編譯時加上 enable pcntl開啟程序控制支援,不是unix類系統不支援此模組 php官網介紹建立子程序需要使用到pcntl fork 文件上介紹該函式說 pcntl fork 在當前程序當前位置產生分支 子程序 譯註 fork是建立了乙個子程序,父...
PHP多程序 4 內部多程序
說的都是只相容unix 伺服器的多程序,下面來講講在window 和 unix 都相容的多程序 這裡是泛指,下面的curl實際上是通過io復用實現的 通過擴充套件實現多執行緒的典型例子是curl,curl 支援多執行緒的抓取網頁的功能。這部分過於抽象,所以,我先給出乙個curl並行抓取多個網頁內容的...
PHP多程序 四 內部多程序
上面乙個系列的教程 用 socket 和 pcntl 實現乙個多程序伺服器 一 php多程序程式設計 一 php多程序程式設計 二 管道通訊 php多程序程式設計 三 多程序抓取網頁的演示 說的都是只相容unix 伺服器的多程序,下面來講講在window 和 unix 都相容的多程序 這裡是泛指,下...