linux下php多線程的妙用
開始用php寫后臺服務(wù)一段時間了.也是在這樣的驅(qū)動下,不斷的學(xué)習(xí)php語法,體驗這一原來一直以為神秘且敬而遠之的神奇語言的魅力.最初看php多線程的資料是為了提高程序的處理能力,充分發(fā)揮linux多任務(wù)的優(yōu)勢.不曾想多線程沒用成反到是帶來了一系列的意外收獲.讓之后的許多問題迎刃而解,不敢獨享特一一道來.
本文所講的東西是源自php的pcntl_fork函數(shù).因為這個函數(shù)依賴操作系統(tǒng)fork的實現(xiàn),所以本文所講的東西只適用于linux/unix.ok,那么先看看這個函數(shù)的用法吧.php手冊上是這么說的:
<?php
$pid = pcntl_fork();
if ($pid == -1) {
die('could not fork');
} else if ($pid) {
// we are the parent
pcntl_wait($status); //Protect against Zombie children
} else {
// we are the child
}
?> 通過pcntl_fork創(chuàng)建一個子進程,如果返回值是-1的話,那么說明子進程創(chuàng)建失敗.創(chuàng)建成功的進程id會返回給父進程,0返回給子進程.不好理解吧,費了很常時間明白以后,筆者習(xí)慣這樣寫:
<?php
$pid = pcntl_fork();
if($pid == -1){
//創(chuàng)建失敗咱就退出唄,沒啥好說的
die('could not fork');
}
else{
if($pid){
//從這里開始寫的代碼是父進程的,因為寫的是系統(tǒng)程序,記得退出的時候給個返回值
exit(0);
}
else{
//從這里開始寫的代碼都是在新的進程里執(zhí)行的,同樣正常退出的話,最好也給一個返回值
exit(0);
}
}
?> 這樣一改好理解多了,如果你父進程希望知道子進程正常退出的話,可以加上前面的pcntl_wait.
函數(shù)的用法是整明白了,在實際的工作中有什么用處呢?
1.后臺程序
命令行程序好寫,服務(wù)程序也好寫,筆者覺得這服務(wù)程序最難寫.想想原來想在windows下寫個服務(wù)啥的,又是要注冊服務(wù)又是要這樣那樣的老費勁了.現(xiàn)在專職管理linux想讓個命令行程序在后臺運行,直接在命令后面加個&就搞定了.但是這樣總覺得土.有了pcntl_fork突然發(fā)現(xiàn)世界是那么的美好.當(dāng)主進程成功創(chuàng)建子進程并獲得子進程的id以后,自己在臨死前還不忘說一句:"我已成功運行,我的id是:xxxx(子進程的id)",完了還給系統(tǒng)返回個0(正常退出),哈哈,死都死的那么有尊嚴(yán).
前面說的是程序常駐內(nèi)存的情況,當(dāng)然了這時候要注意內(nèi)存的釋放以及向日志文件打印信息,而不是往屏幕上(一打印信息程序就退出的喲).還有一種情況是:程序被其它腳本調(diào)用,其它腳本只關(guān)心程序是不是正常運行,如果程序要運行很長時間才能運行完的話,最好不讓腳本等待.這樣的話pcntl_fork又派上用場了:)
2.延時處理.
有的時候,我們程序退出的時候要清理自身產(chǎn)生的東西,比如說要刪除自己(當(dāng)然了linux下面是可以刪除正在運行的文件的,只是舉個例子),這個時候就可以另起動一個進程,然后自己結(jié)束了,把事情交給另一個進程來做.當(dāng)我們寫服務(wù)程序的時候,我們肯定是寫日志文件記錄程序的運行情況(要不誰知道程序是不是在那睡大覺的:0).程序正常退出的時候我們可以寫一條日志說程序退出了,但是當(dāng)程序收到linux下偉大的kill -9的時候,怎么記錄自己的退出行為呢?額.....這個和php的進程信號有關(guān)好像和這個沒多大關(guān)系.
另一種情況:一個完善的程序一般都支持start,stop,restart這樣的參數(shù).start好說,stop也好說,既然start和stop都好說了,這個restart就先stop然后再start就可以了啊.額...好像又和pcntl_fork沒多大關(guān)系,當(dāng)你收到重啟的信號總不能還是kill然后再start吧,是不是太黃太暴力了?還是溫柔一點,讓當(dāng)前進程退出,讓另外的進程再把它拉起來吧.在windows下想實現(xiàn)這一點似乎很困難呢,比如程序更新的時候,一般都是單寫更新程序,或者程序退出的時候另起動一個批處理啟動自己:)
3.不死進程
其實就是傳說中的雙進程了.早些年的時候萬象網(wǎng)管為了達到不被惡意結(jié)束的目的用的就是這招了.雖然咱不用擔(dān)心程序被人惡意停止,但是也保不齊主程序因為任務(wù)太重抗不住自己先掛了(這種情況也不是不會發(fā)生).所以......
說了這么多,只是對寫程序的一些思考,對一個函數(shù)用法的延伸.我想到了這么多,你呢?
關(guān)鍵字:服務(wù)器、多線程、參數(shù)、進程
新文章:
- CentOS7下圖形配置網(wǎng)絡(luò)的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統(tǒng)后丟失windows啟動項
- CentOS單網(wǎng)卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網(wǎng)打印機IP講解
- CentOS7使用hostapd實現(xiàn)無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網(wǎng)絡(luò)重啟出錯
- 解決Centos7雙系統(tǒng)后丟失windows啟動項
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統(tǒng)有什么不同呢
- Centos 6.6默認(rèn)iptable規(guī)則詳解