浅析三种特殊进程:孤儿进程,僵尸进程和守护进程
其實有時想想linux內(nèi)核的設(shè)計也蘊含著很多人生哲學(xué),在linux中有這么幾個特殊進(jìn)程中,我們一開始見到它們的名字可能還會覺得很詫異,但在了解完了原理后,我們仔細(xì)想想,這樣的命名也不無道理!下面我就給大家分別介紹一下這三種特殊的進(jìn)程!
1.孤兒進(jìn)程
如果父進(jìn)程先退出,子進(jìn)程還沒退出那么子進(jìn)程將被 托孤給init進(jìn)程,這是子進(jìn)程的父進(jìn)程就是init進(jìn)程(1號進(jìn)程).其實還是很好理解的.
#include <sys/types.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <signal.h> #include <errno.h> #include <signal.h>int main(void) {pid_t pid ;signal(SIGCHLD,SIG_IGN);printf("before fork pid:%d\n",getpid());int abc = 10;pid = fork();if(pid == -1){perror("tile");return -1;}if(pid > 0) //父進(jìn)程先退出 {abc++;printf("parent:pid:%d \n",getpid());printf("abc:%d \n",abc);sleep(5);}else if(pid == 0){ //值進(jìn)程后退出,被托付給init進(jìn)程abc++;printf("child:%d,parent: %d\n",getpid(),getppid());printf("abc:%d",abc);sleep(100);}printf("fork after...\n"); }
before fork pid:27709
parent:pid:27709
abc:11
child:27710,parent: 27709
fork after...
disda 27710 1 0 10:47 pts/1 00:00:00 ./review
disda 27713 25948 47 10:47 pts/3 00:00:00 ps -ef
我們執(zhí)行程序后由于子進(jìn)程進(jìn)入sleep(100),而父進(jìn)程先退出.通過ps -ef命令我們可以知道,此時27710號進(jìn)程的父進(jìn)程編程了1號進(jìn)程.也就是我們所說的init進(jìn)程.
2.僵尸進(jìn)程
如果我們了解過linux進(jìn)程狀態(tài)及轉(zhuǎn)換關(guān)系,我們應(yīng)該知道進(jìn)程這么多狀態(tài)中有一種狀態(tài)是僵死狀態(tài),就是進(jìn)程終止后進(jìn)入僵死狀態(tài)(zombie),等待告知父進(jìn)程自己終止,后才能完全消失.但是如果一個進(jìn)程已經(jīng)終止了,但是其父進(jìn)程還沒有獲取其狀態(tài),那么這個進(jìn)程就稱之為僵尸進(jìn)程.僵尸進(jìn)程還會消耗一定的系統(tǒng)資源,并且還保留一些概要信息供父進(jìn)程查詢子進(jìn)程的狀態(tài)可以提供父進(jìn)程想要的信息.一旦父進(jìn)程得到想要的信息,僵尸進(jìn)程就會結(jié)束.
int main(void) {pid_t pid ;//signal(SIGCHLD,SIG_IGN);printf("before fork pid:%d\n",getpid());int abc = 10;pid = fork();if(pid == -1){perror("tile");return -1;}if(pid > 0){abc++;printf("parent:pid:%d \n",getpid());printf("abc:%d \n",abc);sleep(20);}else if(pid == 0){abc++;printf("child:%d,parent: %d\n",getpid(),getppid());printf("abc:%d",abc);exit(0);}printf("fork after...\n");
disda 27881 23047 0 11:12 pts/1 00:00:00 ./fork01
disda 27882 27881 0 11:12 pts/1 00:00:00 [fork01] <defunct>
同樣通過ps -ef我們可以得知進(jìn)程信息和進(jìn)程pid,可以看到子進(jìn)程就是處于defunct狀態(tài).這時我們肯定想要怎么才能避免僵尸進(jìn)程呢?看程序被我注釋的那句signal(SIGCHLD,SIG_IGN),加上就不會出現(xiàn)僵尸進(jìn)程了.那我們就加點篇幅講一下為什么就可以避免僵尸進(jìn)程呢?
這是signal()函數(shù)的聲明sighandler_t signal(int signum, sighandler_t handler),我們可以得出,signal函數(shù)的第一個函數(shù)是Linux支持的信號,第二個參數(shù)是對信號的操作?,是系統(tǒng)默認(rèn)還是忽略或捕獲.我們這是就可以知道signal(SIGCHLD,SIG_IGN)是選擇對子程序終止信號選擇忽略,這是僵尸進(jìn)程就是交個內(nèi)核自己處理,并不會產(chǎn)生僵尸進(jìn)程.
3.守護(hù)進(jìn)程
同樣我們需要了解一下什么是守護(hù)進(jìn)程,守護(hù)進(jìn)程就是在后臺運行,不與任何終端關(guān)聯(lián)的進(jìn)程,通常情況下守護(hù)進(jìn)程在系統(tǒng)啟動時就在運行,它們以root用戶或者其他特殊用戶(apache和postfix)運行,并能處理一些系統(tǒng)級的任務(wù).習(xí)慣上守護(hù)進(jìn)程的名字通常以d結(jié)尾(sshd),但這些不是必須的.
下面介紹一下創(chuàng)建守護(hù)進(jìn)程的步驟
- 調(diào)用fork(),創(chuàng)建新進(jìn)程,它會是將來的守護(hù)進(jìn)程.
- 在父進(jìn)程中調(diào)用exit,保證子進(jìn)程不是進(jìn)程組長
- 調(diào)用setsid()創(chuàng)建新的會話區(qū)
- 將當(dāng)前目錄改成跟目錄(如果把當(dāng)前目錄作為守護(hù)進(jìn)程的目錄,當(dāng)前目錄不能被卸載他作為守護(hù)進(jìn)程的工作目錄)
- 將標(biāo)準(zhǔn)輸入,標(biāo)注輸出,標(biāo)準(zhǔn)錯誤重定向到/dev/null
disda ? ?26217 ? ? 1 ?0 06:59 ? ? ? ? ?00:00:00 ./dm01_demon 則出現(xiàn)了守護(hù)進(jìn)程!
來源:http://www.cnblogs.com/wannable/p/6021617.html
總結(jié)
以上是生活随笔為你收集整理的浅析三种特殊进程:孤儿进程,僵尸进程和守护进程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第四套人民币什么时候停止兑换
- 下一篇: 最全的数据结构解析与归纳