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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

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

發(fā)布時間:2023/12/19 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅谈三种特殊进程:孤儿进程,僵尸进程和守护进程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

昨天學了進程控制,就這三種特殊的進程研究了一下,其中也借鑒了一些前人總計的經(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)可以提供父進程想要的信息.一旦父進程得到想要的信息,僵尸進程就會結束.

// 子進程比父進程先退出 int main() {int count = 5;while (count--){//signal(SIGCHLD,SIG_IGN);pid_t pid = fork();switch (pid){case -1:perror ("fork");break;case 0: // 子進程printf ("我是子進程,我的ID是%d\n", getpid());printf ("我走啦\n");exit (0);default: // 父進程printf ("我是父進程,我的ID是%d\n", getpid());//while(1);break;}}while(1);return 0; }

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

// 守護進程 int daemonize (int nochdir, int noclose) {// 創(chuàng)建子進程,關閉父進程pid_t pid = fork();if (pid > 0) // 父進程{exit (0);}else if (pid < 0){return -1;}// 2、設置文件的掩碼,mode & ~umaskumask (0);// 3、設置新的會話:脫離當前會話和終端的控制if (setsid() < 0){return -1;}// 當nochdir為0時,daemon將更改進程的根目錄為rootif (0 == nochdir){// 改變當前的工作目錄if (chdir ("/") < 0){return -1;}}// 標準輸入、關閉標準輸出、標準錯誤close (STDIN_FILENO);close (STDOUT_FILENO);close (STDERR_FILENO);if (0 == noclose){// 重定向標準輸入、關閉標準輸出、標準錯誤open ("dev/null", O_RDONLY); // 0open ("dev/null", O_RDWR); // 1open ("dev/null", O_RDWR); // 2}return 0; }int main() {daemonize (0, 0);// daemon (0,0); // 系統(tǒng)自帶守護進程while (1);return 0; }

總結

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。