孤兒進程
我們經(jīng)常聽別人說到孤兒進程(Orphan Process),究竟是什么呢,現(xiàn)在我們一次理解透。
根據(jù)維基百科的解釋,孤兒進程指的是在其父進程執(zhí)行完成或被終止后仍繼續(xù)運行的一類進程。
孤兒進程與僵尸進程是完全不同的,孤兒進程借用了現(xiàn)實中孤兒的概念,也就是父進程不在了,子進程還在運行,這時我們就把子進程的PPID設(shè)為1。前面講PID提到,操作系統(tǒng)會創(chuàng)建進程號為1的init進程,它沒有父進程也不會退出,可以收養(yǎng)系統(tǒng)的孤兒進程。
作用
在現(xiàn)實中用戶可能刻意使進程成為孤兒進程,這樣就可以讓它與父進程會話脫鉤,成為后面會介紹的守護進程。
僵尸進程
當一個進程完成它的工作終止之后,它的父進程需要調(diào)用wait()或者waitpid()系統(tǒng)調(diào)用取得子進程的終止狀態(tài)。
一個進程使用fork創(chuàng)建子進程,如果子進程退出,而父進程并沒有調(diào)用wait或waitpid獲取子進程的狀態(tài)信息,那么子進程的進程描述符仍然保存在系統(tǒng)中。這種進程稱之為僵死進程。
理解了孤兒進程和僵尸進程,我們臨時加了守護進程這一小節(jié),守護進程就是后臺進程嗎?沒那么簡單。
守護(Daemon)進程
我們可以認為守護進程就是后臺服務(wù)進程,因為它會有一個很長的生命周期提供服務(wù),關(guān)閉終端不會影響服務(wù),也就是說可以忽略某些信號。
實現(xiàn)守護進程
首先要保證進程在后臺運行,可以在啟動程序后面加&,當然更原始的方法是進程自己fork然后結(jié)束父進程。
if (pid=fork()) {
exit(0); // Parent process
}
然后是與終端、進程組、會話(Session)分離。每個進程創(chuàng)建時都綁定一個終端,而且屬于一個進程組(進程組也有GID不過等同進程組長的PID),這些進程組在一個會話中,如果是子進程一般會從父進程繼承這些信息,想要與環(huán)境分離可以使用以下的系統(tǒng)調(diào)用。
setsid();
同樣地我們會從父進程繼承文件掩碼(mask),可以手動清理掩碼。
umask(0);
如果需要我們可以改變當前工作目錄,避免運行時必須使用當前所在的文件系統(tǒng)。
使用Nohup
前面提到過nohup命令,是讓程序以守護進程運行的方式之一,程序運行后忽略SIGHUP信號,也就說關(guān)閉終端不會影響進程的運行。類似的命令還有disown,這里不再詳述。