


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