浅谈三种特殊进程:孤儿进程,僵尸进程和守护进程
昨天學了進程控制,就這三種特殊的進程研究了一下,其中也借鑒了一些前人總計的經(jīng)驗。
1、孤兒進程
如果父進程先退出,子進程還沒退出那么子進程將被 托孤給init進程,這里子進程的父進程就是init進程(1號進程).其實還是很好理解的。
// 父進程先子進程退出 // 子進程會被祖父進程接手并在后臺運行,執(zhí)行內(nèi)部的代碼 int main() {pid_t pid = fork();switch (pid){case -1:perror ("fork");break;case 0: // 子進程close (1);// 創(chuàng)建一個文件用來保存輸出的文字int fd = open ("child", O_RDWR|O_CREAT, 0777);printf ("我是子進程,我的ID是%d\n", getpid());while (1){printf ("找爸爸\n");fflush (stdout);sleep (2);}break;default: // 父進程printf ("我是父進程:ID = %d\n", getpid());printf ("我走啦\n");while (1);break;}return 0; }
在這里我們運行了程序,可以在另一終端看到有2個a.out在運行,我們將父進程終止,子進程并沒有退出,而是在后臺繼續(xù)運行,并向child文件中輸出文字。
2、僵尸進程
如果我們了解過Linux進程狀態(tài)及轉換關系,我們應該知道進程這么多狀態(tài)中有一種狀態(tài)是僵死狀態(tài),就是進程終止后進入僵死狀態(tài)(zombie),等待告知父進程自己終止,后才能完全消失.但是如果一個進程已經(jīng)終止了,但是其父進程還沒有獲取其狀態(tài),那么這個進程就稱之為僵尸進程.僵尸進程還會消耗一定的系統(tǒng)資源,并且還保留一些概要信息供父進程查詢子進程的狀態(tài)可以提供父進程想要的信息.一旦父進程得到想要的信息,僵尸進程就會結束.
signal(SIGCHLD,SIG_IGN);加上這行代碼后僵尸進程都消失了。
通過ps -ef | grep a.out 我們可以得知進程信息和進程pid,可以看到子進程就是處于defunct狀態(tài).這時我們肯定想要怎么才能避免僵尸進程呢?看程序被我注釋的那句signal(SIGCHLD,SIG_IGN),加上就不會出現(xiàn)僵尸進程了.那我們就加點篇幅講一下為什么就可以避免僵尸進程呢?
這是signal()函數(shù)的聲明sighandler_t signal(int signum, sighandler_t handler),我們可以得出,signal函數(shù)的第一個函數(shù)是linux支持的信號,第二個參數(shù)是對信號的操作 ,是系統(tǒng)默認還是忽略或捕獲.我們這是就可以知道signal(SIGCHLD,SIG_IGN)是選擇對子程序終止信號選擇忽略,這是僵尸進程就是交個內(nèi)核自己處理,并不會產(chǎn)生僵尸進程.
3、守護進程
同樣我們需要了解一下什么是守護進程,守護進程就是在后臺運行,不與任何終端關聯(lián)的進程,通常情況下守護進程在系統(tǒng)啟動時就在運行,它們以root用戶或者其他特殊用戶(apache和postfix)運行,并能處理一些系統(tǒng)級的任務.習慣上守護進程的名字通常以d結尾(sshd),但這些不是必須的.
下面介紹一下創(chuàng)建守護進程的步驟:
· 調(diào)用fork(),創(chuàng)建新進程,它會是將來的守護進程.
· 在父進程中調(diào)用exit,保證子進程不是進程組長
· 調(diào)用setsid()創(chuàng)建新的會話區(qū)
· 將當前目錄改成跟目錄(如果把當前目錄作為守護進程的目錄,當前 目錄不能被卸載他作為守護進程的工作目錄)
· 將標準輸入,標注輸出,標準錯誤重定向到/dev/null
總結
以上是生活随笔為你收集整理的浅谈三种特殊进程:孤儿进程,僵尸进程和守护进程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何测试程序是否_软件开发过程中,如何进
- 下一篇: shell关闭指定进程