開始用php寫后臺服務一段時間了.也是在這樣的驅動下,不斷的學習php語法,體驗這一原來一直以為神秘且敬而遠之的神奇語言的魅力.最初看php多線程的資料是為了提高程序的處理能力,充分發揮linux多任務的優勢.不曾想多線程沒用成反到是帶來了一系列的意外收獲.讓之后的許多問題迎刃而解,不敢獨享特一一道來.
本文所講的東西是源自php的pcntl_fork函數.因為這個函數依賴操作系統fork的實現,所以本文所講的東西只適用于linux/unix.ok,那么先看看這個函數的用法吧.php手冊上是這么說的:
通過pcntl_fork創建一個子進程,如果返回值是-1的話,那么說明子進程創建失敗.創建成功的進程id會返回給父進程,0返回給子進程.不好理解吧,費了很常時間明白以后,筆者習慣這樣寫:
這樣一改好理解多了,如果你父進程希望知道子進程正常退出的話,可以加上前面的pcntl_wait.
函數的用法是整明白了,在實際的工作中有什么用處呢?
1.后臺程序
命令行程序好寫,服務程序也好寫,筆者覺得這服務程序最難寫.想想原來想在windows下寫個服務啥的,又是要注冊服務又是要這樣那樣的老費勁了.現在專職管理linux想讓個命令行程序在后臺運行,直接在命令后面加個&就搞定了.但是這樣總覺得土.有了pcntl_fork突然發現世界是那么的美好.當主進程成功創建子進程并獲得子進程的id以后,自己在臨死前還不忘說一句:"我已成功運行,我的id是:xxxx(子進程的id)",完了還給系統返回個0(正常退出),哈哈,死都死的那么有尊嚴.
前面說的是程序常駐內存的情況,當然了這時候要注意內存的釋放以及向日志文件打印信息,而不是往屏幕上(一打印信息程序就退出的喲).還有一種情況是:程序被其它腳本調用,其它腳本只關心程序是不是正常運行,如果程序要運行很長時間才能運行完的話,最好不讓腳本等待.這樣的話pcntl_fork又派上用場了:)
2.延時處理.
有的時候,我們程序退出的時候要清理自身產生的東西,比如說要刪除自己(當然了linux下面是可以刪除正在運行的文件的,只是舉個例子),這個時候就可以另起動一個進程,然后自己結束了,把事情交給另一個進程來做.當我們寫服務程序的時候,我們肯定是寫日志文件記錄程序的運行情況(要不誰知道程序是不是在那睡大覺的:0).程序正常退出的時候我們可以寫一條日志說程序退出了,但是當程序收到linux下偉大的kill -9的時候,怎么記錄自己的退出行為呢?額.....這個和php的進程信號有關好像和這個沒多大關系.
另一種情況:一個完善的程序一般都支持start,stop,restart這樣的參數.start好說,stop也好說,既然start和stop都好說了,這個restart就先stop然后再start就可以了啊.額...好像又和pcntl_fork沒多大關系,當你收到重啟的信號總不能還是kill然后再start吧,是不是太黃太暴力了?還是溫柔一點,讓當前進程退出,讓另外的進程再把它拉起來吧.在windows下想實現這一點似乎很困難呢,比如程序更新的時候,一般都是單寫更新程序,或者程序退出的時候另起動一個批處理啟動自己:)
3.不死進程
其實就是傳說中的雙進程了.早些年的時候萬象網管為了達到不被惡意結束的目的用的就是這招了.雖然咱不用擔心程序被人惡意停止,但是也保不齊主程序因為任務太重抗不住自己先掛了(這種情況也不是不會發生).所以......
說了這么多,只是對寫程序的一些思考,對一個函數用法的延伸.我想到了這么多,你呢?
新聞熱點
疑難解答