国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

首頁 后端開發(fā) php教程 使用PHP腳本來寫Daemon程序_PHP教程

使用PHP腳本來寫Daemon程序_PHP教程

Jul 21, 2016 pm 02:58 PM
php 什么 使用 概念 程序 腳本 進程

什么是Daemon進程

這又是一個有趣的概念,daemon在英語中是"精靈"的意思,就像我們經(jīng)常在迪斯尼動畫里見到的那些,有些會飛,有些不會,經(jīng)常圍著動畫片的主人公轉(zhuǎn)來轉(zhuǎn)去,啰里啰唆地提一些忠告,時不時倒霉地撞在柱子上,有時候還會想出一些小小的花招,把主人公從敵人手中救出來,正因如此,daemon有時也被譯作"守護神"。所以,daemon進程在國內(nèi)也有兩種譯法,有些人譯作"精靈進程",有些人譯作"守護進程",這兩種稱呼的出現(xiàn)頻率都很高。

與真正的daemon相似,daemon進程也習慣于把自己隱藏在人們的視線之外,默默為系統(tǒng)做出貢獻,有時人們也把它們稱作"后臺服務進程"。daemon進程的壽命很長,一般來說,從它們一被執(zhí)行開始,直到整個系統(tǒng)關閉,它們才會退出。幾乎所有的服務器程序,包括我們熟知的Apache和wu-FTP,都用daemon進程的形式實現(xiàn)。很多Linux下常見的命令如inetd和ftpd,末尾的字母d就是指daemon。

為什么一定要使用daemon進程呢?Linux中每一個系統(tǒng)與用戶進行交流的界面稱為終端(terminal),每一個從此終端開始運行的進程都會依附于這個終端,這個終端就稱為這些進程的控制終端(Controlling terminal),當控制終端被關閉時,相應的進程都會被自動關閉。關于這點,讀者可以用X-Window中的XTerm試驗一下,(每一個XTerm就是一個打開的終端,)我們可以通過鍵入命令啟動應用程序,比如:$netscape 然后我們關閉XTerm窗口,剛剛啟動的netscape窗口也會隨之一同突然蒸發(fā)。但是daemon進程卻能夠突破這種限制,即使對應的終端關閉,它也能在系統(tǒng)中長久地存在下去,如果我們想讓某個進程長命百歲,不因為用戶或終端或其他的變化而受到影響,就必須把這個進程變成一個daemon進程。

Daemon進程的編程規(guī)則

如果想把自己的進程變成daemon進程,我們必須嚴格按照以下步驟進行:

1、調(diào)用fork產(chǎn)生一個子進程,同時父進程退出。我們所有后續(xù)工作都在子進程中完成。這樣做我們可以:

1.1 如果我們是從命令行執(zhí)行的該程序,這可以造成程序執(zhí)行完畢的假象,shell會回去等待下一條命令;

1.2 剛剛通過fork產(chǎn)生的新進程一定不會是一個進程組的組長,這為第2步的執(zhí)行提供了前提保障。

這樣做還會出現(xiàn)一種很有趣的現(xiàn)象:由于父進程已經(jīng)先于子進程退出,會造成子進程沒有父進程,變成一個孤兒進程(orphan)。每當系統(tǒng)發(fā)現(xiàn)一個孤兒進程,就會自動由1號進程收養(yǎng)它,這樣,原先的子進程就會變成1號進程的子進程。

2、調(diào)用setsid系統(tǒng)調(diào)用。這是整個過程中最重要的一步。setsid的介紹見附錄2,它的作用是創(chuàng)建一個新的會話(session),并自任該會話的組長(session leader)。如果調(diào)用進程是一個進程組的組長,調(diào)用就會失敗,但這已經(jīng)在第1步得到了保證。調(diào)用setsid有3個作用:

2.1 讓進程擺脫原會話的控制;

2.2 讓進程擺脫原進程組的控制;

2.3 讓進程擺脫原控制終端的控制;

總之,就是讓調(diào)用進程完全獨立出來,脫離所有其他進程的控制。

3、把當前工作目錄切換到根目錄。

如果我們是在一個臨時加載的文件系統(tǒng)上執(zhí)行這個進程的,比如:/mnt/floppy/,該進程的當前工作目錄就會是/mnt/floppy/。在整個進程運行期間該文件系統(tǒng)都無法被卸下(umount),而無論我們是否在使用這個文件系統(tǒng),這會給我們帶來很多不便。解決的方法是使用chdir系統(tǒng)調(diào)用把當前工作目錄變?yōu)楦夸?,應該不會有人想把根目錄卸下吧?/p>

關于chdir的用法,參見附錄1。

當然,在這一步里,如果有特殊的需要,我們也可以把當前工作目錄換成其他的路徑,比如/tmp。

4、將文件權(quán)限掩碼設為0。

這需要調(diào)用系統(tǒng)調(diào)用umask,參見附錄3。每個進程都會從父進程那里繼承一個文件權(quán)限掩碼,當創(chuàng)建新文件時,這個掩碼被用于設定文件的默認訪問權(quán)限,屏蔽掉某些權(quán)限,如一般用戶的寫權(quán)限。當另一個進程用exec調(diào)用我們編寫的daemon程序時,由于我們不知道那個進程的文件權(quán)限掩碼是什么,這樣在我們創(chuàng)建新文件時,就會帶來一些麻煩。所以,我們應該重新設置文件權(quán)限掩碼,我們可以設成任何我們想要的值,但一般情況下,大家都把它設為0,這樣,它就不會屏蔽用戶的任何操作。

如果你的應用程序根本就不涉及創(chuàng)建新文件或是文件訪問權(quán)限的設定,你也完全可以把文件權(quán)限掩碼一腳踢開,跳過這一步。

5、關閉所有不需要的文件。

同文件權(quán)限掩碼一樣,我們的新進程會從父進程那里繼承一些已經(jīng)打開了的文件。這些被打開的文件可能永遠不被我們的daemon進程讀或?qū)?,但它們一樣消耗系統(tǒng)資源,而且可能導致所在的文件系統(tǒng)無法卸下。需要指出的是,文件描述符為0、1和2的三個文件(文件描述符的概念將在下一章介紹),也就是我們常說的輸入、輸出和報錯這三個文件也需要被關閉。很可能不少讀者會對此感到奇怪,難道我們不需要輸入輸出嗎?但事實是,在上面的第2步后,我們的daemon進程已經(jīng)與所屬的控制終端失去了聯(lián)系,我們從終端輸入的字符不可能達到daemon進程,daemon進程用常規(guī)的方法(如printf)輸出的字符也不可能在我們的終端上顯示出來。所以這三個文件已經(jīng)失去了存在的價值,也應該被關閉。

使用PHP編寫Gearman的Worker守護進程

在我之前的文章中,介紹過Gearman的使用。在我的項目中,我使用了PHP來編寫一直運行的Worker。如果按照Gearman官方推薦的例子,只是簡單的一個循環(huán)來等待任務,會有一些問題,包括:1、當代碼進行過修改之后,如何讓代碼的修改生效;2、重啟Worker的時候,如何保證當前的任務處理完成才重啟。

針對這個問題,我考慮了以下的解決方法:

1、每次修改完代碼后,Worker需要手工重啟(先殺死然后啟動)。這個只能解決重新加載配置文件的問題。

2、在Worker中設置,單次任務循環(huán)完成后,就對Worker進行重啟。這個方案的問題在于消耗比較大。

3、在Worker中添加一個退出函數(shù),如果需要Worker退出的時候,在Client端發(fā)送一個優(yōu)先級比較高的退出調(diào)用。這個需要客戶端配合,在使用后臺類任務時,不太適合。

4、在Worker中檢查文件是否發(fā)生變化,如果發(fā)生了變化,退出并重啟自身。

5、為Worker編寫信號控制,接受重啟指令,類似于 http restart graceful 指令。

最后,結(jié)合4和5兩種方法,可以實現(xiàn)這樣一個Daemon,如果配置文件發(fā)生了變化,他就會自動重啟;如果接受到了用戶的 kill -1 pid 信號,也會重新啟動。

代碼如下:

Copy to ClipboardLiehuo.Net Codes引用的內(nèi)容:[www.bkjia.com]
declare( ticks = 1 );
// This case will check the config file regularly, if the config file changed, it will restart it self
// If you want to restart the daemon gracefully, give it a HUP signal
// by shiqiang at 2011-12-04

$init_md5 = md5_file( 'config.php');

// register signal handler
pcntl_signal( SIGALRM, "signal_handler", true );
pcntl_signal( SIGHUP, 'signal_handler', TRUE );

$job_flag = FALSE; //Job status flag, to justify if the job has been finished
$signal_flag = FALSE; //Signal status flag, to justify whether we received the kill -1 signal

while( 1 ){
$job_flag = FALSE; //Job status flag
print "Worker start running ... \n";
sleep(5);
print "Worker's task done ... \n";
$flag = TRUE; //Job status flag
AutoStart( $signal_flag );
}

function signal_handler( $signal ) {
global $job_flag;
global $signal_flag;

switch( $signal ){
case SIGQUIT:
print date('y-m-d H:i:s', time() ) . " Caught Signal : SIGQUIT - No : $signal \n";
exit(0);
break;
case SIGSTOP:
print date('y-m-d H:i:s', time() ) . " Caught Signal : SIGSTOP - No : $signal \n";
break;
case SIGHUP:
print date('y-m-d H:i:s', time() ) . " Caught Signal : SIGHUP - No : $signal \n";
if( $flag === TRUE ){
AutoStart( TRUE );
}else{
$signal_flag = TRUE;
}
break;
case SIGALRM:
print date('y-m-d H:i:s', time() ) . " Caught Signal : SIGALRM - No : $signal \n";
//pcntl_exec( '/bin/ls' );
pcntl_alarm( 5 );
break;
default:
break;
}
}

function AutoStart( $signal = FALSE, $filename = 'config.php' ){
global $init_md5;

if( $signal || md5_file( $filename ) != $init_md5 ){
print "The config file has been changed, we are going to restart. \n";
$pid = pcntl_fork();
if( $pid == -1 ){
print "Fork error \n";
}else if( $pid > 0 ){
print "Parent exit \n";
exit(0);
}else{
$init_md5 = md5_file( $filename );
print "Child continue to run \n";
}
}
}

(本文來源:博客園,作者:小狼的世界)

www.bkjia.comtruehttp://www.bkjia.com/PHPjc/363858.htmlTechArticle什么是Daemon進程 這又是一個有趣的概念,daemon在英語中是精靈的意思,就像我們經(jīng)常在迪斯尼動畫里見到的那些,有些會飛,有些不會,經(jīng)...
本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻,版權(quán)歸原作者所有,本站不承擔相應法律責任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動的應用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機

Video Face Swap

Video Face Swap

使用我們完全免費的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級代碼編輯軟件(SublimeText3)

發(fā)電機如何在PHP中工作? 發(fā)電機如何在PHP中工作? Jul 11, 2025 am 03:12 AM

AgeneratorinPHPisamemory-efficientwaytoiterateoverlargedatasetsbyyieldingvaluesoneatatimeinsteadofreturningthemallatonce.1.Generatorsusetheyieldkeywordtoproducevaluesondemand,reducingmemoryusage.2.Theyareusefulforhandlingbigloops,readinglargefiles,or

如何通過php中的索引訪問字符串中的字符 如何通過php中的索引訪問字符串中的字符 Jul 12, 2025 am 03:15 AM

在PHP中獲取字符串特定索引字符可用方括號或花括號,但推薦方括號;索引從0開始,超出范圍訪問返回空值,不可賦值;處理多字節(jié)字符需用mb_substr。例如:$str="hello";echo$str[0];輸出h;而中文等字符需用mb_substr($str,1,1)獲取正確結(jié)果;實際應用中循環(huán)訪問前應檢查字符串長度,動態(tài)字符串需驗證有效性,多語言項目建議統(tǒng)一使用多字節(jié)安全函數(shù)。

如何防止PHP中的會話劫持? 如何防止PHP中的會話劫持? Jul 11, 2025 am 03:15 AM

要防止PHP中的會話劫持,需采取以下措施:1.使用HTTPS加密傳輸并在php.ini中設置session.cookie_secure=1;2.設置安全Cookie屬性,包括httponly、secure和samesite;3.在用戶登錄或權(quán)限變更時調(diào)用session_regenerate_id(true)更換SessionID;4.限制Session生命周期,合理配置gc_maxlifetime并記錄用戶活動時間;5.禁止將SessionID暴露在URL中,設置session.use_only

如何用urlencode在PHP中編碼字符串 如何用urlencode在PHP中編碼字符串 Jul 11, 2025 am 03:22 AM

urlencode()函數(shù)用于將字符串編碼為URL安全格式,其中非字母數(shù)字字符(除-、_和.外)會被替換為百分號后跟兩位十六進制數(shù)的形式。例如,空格轉(zhuǎn)為 號,感嘆號轉(zhuǎn)為!,而中文字符則轉(zhuǎn)換為其UTF-8編碼形式。使用時應僅對參數(shù)值進行編碼,而非整個URL,以避免破壞URL結(jié)構(gòu)。對于URL的其他部分如路徑段,應使用rawurlencode()函數(shù),其將空格轉(zhuǎn)為 。處理數(shù)組參數(shù)時可使用http_build_query()自動編碼,或手動對每個值調(diào)用urlencode()以確保安全傳輸數(shù)據(jù)。正

php獲得字符串的第一個N字符 php獲得字符串的第一個N字符 Jul 11, 2025 am 03:17 AM

在PHP中取字符串前N個字符可用substr()或mb_substr(),具體步驟如下:1.使用substr($string,0,N)截取前N個字符,適用于ASCII字符且簡單高效;2.處理多字節(jié)字符(如中文)時應使用mb_substr($string,0,N,'UTF-8'),并確保啟用mbstring擴展;3.若字符串含HTML或空白字符,應先用strip_tags()去除標簽、trim()清理空格,再截取以保證結(jié)果干凈。

PHP獲得字符串的最后N字符 PHP獲得字符串的最后N字符 Jul 11, 2025 am 03:17 AM

在PHP中獲取字符串最后N個字符主要有兩種方法:1.使用substr()函數(shù),通過負數(shù)起始位置截取,適用于單字節(jié)字符;2.使用mb_substr()函數(shù),支持多語言和UTF-8編碼,避免截斷非英文字符;3.可選地判斷字符串長度是否足夠以處理邊界情況;4.不推薦使用strrev() substr()的組合方式,因其對多字節(jié)字符不安全且效率低。

如何在PHP中設置和獲取會話變量? 如何在PHP中設置和獲取會話變量? Jul 12, 2025 am 03:10 AM

要設置和獲取PHP中的會話變量,首先必須始終在腳本頂部調(diào)用session_start()以啟動會話。1.設置會話變量時,使用$_SESSION超全局數(shù)組為特定鍵賦值,如$_SESSION['username']='john_doe';可存儲字符串、數(shù)字、數(shù)組甚至對象,但避免存儲過多數(shù)據(jù)以免影響性能。2.獲取會話變量時,需先調(diào)用session_start(),然后通過鍵訪問$_SESSION數(shù)組,如echo$_SESSION['username'];建議使用isset()檢查變量是否存在以避免錯誤

如何防止PHP中的SQL注入 如何防止PHP中的SQL注入 Jul 12, 2025 am 03:02 AM

防止SQL注入在PHP中的關鍵方法包括:1.使用預處理語句(如PDO或MySQLi)分離SQL代碼和數(shù)據(jù);2.關閉模擬預處理模式確保真正預處理;3.對用戶輸入進行過濾和驗證,如使用is_numeric()和filter_var();4.避免直接拼接SQL字符串,改用參數(shù)綁定;5.生產(chǎn)環(huán)境關閉錯誤顯示并記錄錯誤日志。這些措施從機制和細節(jié)上全面防范SQL注入風險。

See all articles