孤兒進(jìn)程
我們經(jīng)常聽別人說到孤兒進(jìn)程(Orphan Process),究竟是什么呢捌刮,現(xiàn)在我們一次理解透碰煌。
根據(jù)維基百科的解釋,孤兒進(jìn)程指的是在其父進(jìn)程執(zhí)行完成或被終止后仍繼續(xù)運(yùn)行的一類進(jìn)程绅作。
孤兒進(jìn)程與僵尸進(jìn)程是完全不同的芦圾,孤兒進(jìn)程借用了現(xiàn)實(shí)中孤兒的概念,也就是父進(jìn)程不在了俄认,子進(jìn)程還在運(yùn)行个少,這時(shí)我們就把子進(jìn)程的PPID設(shè)為1。前面講PID提到眯杏,操作系統(tǒng)會創(chuàng)建進(jìn)程號為1的init進(jìn)程夜焦,它沒有父進(jìn)程也不會退出,可以收養(yǎng)系統(tǒng)的孤兒進(jìn)程岂贩。
作用
在現(xiàn)實(shí)中用戶可能刻意使進(jìn)程成為孤兒進(jìn)程茫经,這樣就可以讓它與父進(jìn)程會話脫鉤,成為后面會介紹的守護(hù)進(jìn)程河闰。
僵尸進(jìn)程
當(dāng)一個(gè)進(jìn)程完成它的工作終止之后科平,它的父進(jìn)程需要調(diào)用wait()或者waitpid()系統(tǒng)調(diào)用取得子進(jìn)程的終止?fàn)顟B(tài)。
一個(gè)進(jìn)程使用fork創(chuàng)建子進(jìn)程姜性,如果子進(jìn)程退出瞪慧,而父進(jìn)程并沒有調(diào)用wait或waitpid獲取子進(jìn)程的狀態(tài)信息,那么子進(jìn)程的進(jìn)程描述符仍然保存在系統(tǒng)中部念。這種進(jìn)程稱之為僵死進(jìn)程弃酌。
理解了孤兒進(jìn)程和僵尸進(jìn)程,我們臨時(shí)加了守護(hù)進(jìn)程這一小節(jié)儡炼,守護(hù)進(jìn)程就是后臺進(jìn)程嗎妓湘?沒那么簡單。
守護(hù)(Daemon)進(jìn)程
我們可以認(rèn)為守護(hù)進(jìn)程就是后臺服務(wù)進(jìn)程乌询,因?yàn)樗鼤幸粋€(gè)很長的生命周期提供服務(wù)榜贴,關(guān)閉終端不會影響服務(wù),也就是說可以忽略某些信號妹田。
實(shí)現(xiàn)守護(hù)進(jìn)程
首先要保證進(jìn)程在后臺運(yùn)行唬党,可以在啟動程序后面加&鹃共,當(dāng)然更原始的方法是進(jìn)程自己fork然后結(jié)束父進(jìn)程。
if (pid=fork()) {
exit(0); // Parent process
}
然后是與終端驶拱、進(jìn)程組霜浴、會話(Session)分離。每個(gè)進(jìn)程創(chuàng)建時(shí)都綁定一個(gè)終端蓝纲,而且屬于一個(gè)進(jìn)程組(進(jìn)程組也有GID不過等同進(jìn)程組長的PID)阴孟,這些進(jìn)程組在一個(gè)會話中,如果是子進(jìn)程一般會從父進(jìn)程繼承這些信息税迷,想要與環(huán)境分離可以使用以下的系統(tǒng)調(diào)用永丝。
setsid();
同樣地我們會從父進(jìn)程繼承文件掩碼(mask),可以手動清理掩碼翁狐。
umask(0);
如果需要我們可以改變當(dāng)前工作目錄类溢,避免運(yùn)行時(shí)必須使用當(dāng)前所在的文件系統(tǒng)。
使用Nohup
前面提到過nohup命令露懒,是讓程序以守護(hù)進(jìn)程運(yùn)行的方式之一闯冷,程序運(yùn)行后忽略SIGHUP信號,也就說關(guān)閉終端不會影響進(jìn)程的運(yùn)行懈词。類似的命令還有disown蛇耀,這里不再詳述。