日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

浅析三种特殊进程:孤儿进程,僵尸进程和守护进程.

發布時間:2024/2/28 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅析三种特殊进程:孤儿进程,僵尸进程和守护进程. 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

其實有時想想linux內核的設計也蘊含著很多人生哲學,在linux中有這么幾個特殊進程中,我們一開始見到它們的名字可能還會覺得很詫異,但在了解完了原理后,我們仔細想想,這樣的命名也不無道理!下面我就給大家分別介紹一下這三種特殊的進程!

  1.孤兒進程

  如果父進程先退出,子進程還沒退出那么子進程將被 托孤給init進程,這是子進程的父進程就是init進程(1號進程).其實還是很好理解的.

  

#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) //父進程先退出 {abc++;printf("parent:pid:%d \n",getpid());printf("abc:%d \n",abc);sleep(5);}else if(pid == 0){ //值進程后退出,被托付給init進程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

  我們執行程序后由于子進程進入sleep(100),而父進程先退出.通過ps -ef命令我們可以知道,此時27710號進程的父進程編程了1號進程.也就是我們所說的init進程.

  2.僵尸進程

  如果我們了解過linux進程狀態及轉換關系,我們應該知道進程這么多狀態中有一種狀態是僵死狀態,就是進程終止后進入僵死狀態(zombie),等待告知父進程自己終止,后才能完全消失.但是如果一個進程已經終止了,但是其父進程還沒有獲取其狀態,那么這個進程就稱之為僵尸進程.僵尸進程還會消耗一定的系統資源,并且還保留一些概要信息供父進程查詢子進程的狀態可以提供父進程想要的信息.一旦父進程得到想要的信息,僵尸進程就會結束.

  

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我們可以得知進程信息和進程pid,可以看到子進程就是處于defunct狀態.這時我們肯定想要怎么才能避免僵尸進程呢?看程序被我注釋的那句signal(SIGCHLD,SIG_IGN),加上就不會出現僵尸進程了.那我們就加點篇幅講一下為什么就可以避免僵尸進程呢?

這是signal()函數的聲明sighandler_t signal(int signum, sighandler_t handler),我們可以得出,signal函數的第一個函數是Linux支持的信號,第二個參數是對信號的操作?,是系統默認還是忽略或捕獲.我們這是就可以知道signal(SIGCHLD,SIG_IGN)是選擇對子程序終止信號選擇忽略,這是僵尸進程就是交個內核自己處理,并不會產生僵尸進程.

  3.守護進程

  同樣我們需要了解一下什么是守護進程,守護進程就是在后臺運行,不與任何終端關聯的進程,通常情況下守護進程在系統啟動時就在運行,它們以root用戶或者其他特殊用戶(apache和postfix)運行,并能處理一些系統級的任務.習慣上守護進程的名字通常以d結尾(sshd),但這些不是必須的.

  下面介紹一下創建守護進程的步驟

  • 調用fork(),創建新進程,它會是將來的守護進程.
  • 在父進程中調用exit,保證子進程不是進程組長
  • 調用setsid()創建新的會話區
  • 將當前目錄改成跟目錄(如果把當前目錄作為守護進程的目錄,當前目錄不能被卸載他作為守護進程的工作目錄)
  • 將標準輸入,標注輸出,標準錯誤重定向到/dev/null
#include <sys/types.h> #incldue <sys/stat.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <signal.h> #include <errno.h> #include <signal.h> #include <fcntl.h> #incldue <unistd.h> #include <linux/fs.h>int main(void) {pid_t pid;int i;pid = fork(); //創建一個新進程,將來會是守護進程if(pid == -1){return -1;}else if(pid != 0){ //父進程調用exit,保證子進程不是進程組長 exit(EXIT_SUCCESS);}if(setsid() == -1) //創建新的會話區 {return -1; }if(chdir("/") == -1) //將當前目錄改成根目錄 {return -1;}for(i = 0;i < NR_OPEN;i++){close(i);}open("/dev/null",O_RDWR); 重定向dup(0);dup(0);return 0; }

disda ? ?26217 ? ? 1 ?0 06:59 ? ? ? ? ?00:00:00 ./dm01_demon 則出現了守護進程!

總結

以上是生活随笔為你收集整理的浅析三种特殊进程:孤儿进程,僵尸进程和守护进程.的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。