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