搜尋
首頁運維linux運維linux 殭屍行程是什麼

linux 殭屍行程是什麼

Apr 06, 2023 am 11:37 AM
linux殭屍行程

linux殭屍進程是一個早已死亡的進程,但是在進程表中仍佔了一個位置;如果子進程死亡時父進程沒有wait(),通常用ps可以看到它被顯示為“ ”,這樣就產生了殭屍進程;如果大量產生殭屍進程,那麼將因為沒有可用的進程號而導致系統不能產生新的進程,所以要避免有殭屍進程。

linux 殭屍行程是什麼

本教學操作環境:linux5.9.8系統、Dell G3電腦。

linux下殭屍行程(Defunct行程)的產生與避免

一、什麼是殭屍行程

在UNIX 系統中,一個行程結束了,但是他的父行程沒有等待(呼叫wait / waitpid)他,那麼他將變成一個殭屍行程。當用ps指令觀察進程的執行狀態時,看到這些行程的狀態列為defunct。殭屍行程是一個早已死亡的過程,但在行程表(processs table)中仍佔了一個位置(slot)。

但是如果該行程的父行程已經先結束了,那麼該行程就不會變成殭屍行程。因為每個進程結束的時候,系統都會掃描當前系統中所運行的所有進程,看看有沒有哪個進程是剛結束的這個進程的子進程,如果是的話,就由Init進程來接管他,成為他的父進程,從而保證每個進程都會有一個父進程。而Init行程會自動wait其子程序,因此被Init接管的所有行程都不會變成殭屍行程。

二、UNIX下進程的運作方式

每個Unix進程在進程表裡都有一個進入點(entry),核心進程執行該進程時使用到的一切資訊都儲存在進入點。當用 ps 指令察看系統中的進程資訊時,看到的就是進程表中的相關資料。當以fork()系統呼叫建立一個新的進程後,核心進程就會在進程表中給這個新進程分配一個進入點,然後將相關資訊儲存在該進入點所對應的進程表內。這些資訊中有一項是其父進程的識別碼。

子程序的結束和父進程的運行是一個非同步過程,即父進程永遠無法預測子進程到底什麼時候結束。那麼會不會因為父進程太忙來不及 wait 子進程,或是說不知道子進程什麼時候結束,而丟失子進程結束時的狀態資訊呢?

不會。因為UNIX提供了一個機制可以保證,只要父行程想知道子行程結束時的狀態訊息,就可以得到。這個機制就是:當子行程走完了自己的生命週期後,它會執行exit()系統調用,內核釋放該行程所有的資源,包括開啟的文件,佔用的記憶體等。但仍為其保留一定的資訊(包括進程號the process ID,退出碼exit code,退出狀態the terminationstatus of the process,運行時間the amount of CPU time taken by the process等),這些資料會保留到系統將它傳遞給它的父進程為止,直到父進程透過wait / waitpid來取時才釋放。

也就是說,當一個過程死亡時,它並不是完全的消失了。進程終止,它不再運行,但是還有一些殘留的資料等待父進程收回。當父行程 fork() 一個子程序後,它必須用 wait() (或 waitpid())等待子程序退出。正是這個 wait() 動作來讓子程序的殘留資料消失。

三、殭屍行程的危害

如果父行程不呼叫wait / waitpid的話,那麼保留的那段資訊就不會釋放,其行程號碼就會一直被佔用,但是系統的進程表容量是有限的,所能使用的進程號也是有限的,如果大量的產生殭屍進程,將因為沒有可用的進程號而導致系統不能產生新的進程。

所以,defunct進程不僅佔用系統的記憶體資源,影響系統的效能,而且如果其數目太多,還會導致系統癱瘓。而且,由於調度程式無法選取Defunct 進程,所以不能用kill指令刪除Defunct 進程,惟一的方法只有重啟系統。

四、殭屍進程的產生

如果子進程死亡時父進程沒有wait(),通常用ps 可以看到它被顯示為“”,這樣就產生了殭屍行程。它將永遠保持這樣直到父進程 wait()。

由此可見,defunct進程的出現時間是在子程序終止後,但是父進程尚未讀取這些資料之前。利用這一點我們可以用下面的程式建立一個defunct 進程:

#include <stdio.h> 
 
#include<sys> 
 
main()  
{  
 
 if(!fork())  
    {  
 
        printf(“child pid=%d\n”, getpid());  
 
        exit(0);  
 
    }  
 
    sleep(20);  
 
    printf(“parent pid=%d \n”, getpid());  
 
    exit(0);  
 
}</sys></stdio.h>

当上述程序以后台的方式执行时,第17行强迫程序睡眠20秒,让用户有时间输入ps -e指令,观察进程的状态,我们看到进程表中出现了defunct进程。当父进程执行终止后,再用ps -e命令观察时,我们会发现defunct进程也随之消失。这是因为父进程终止后,init 进程会接管父进程留下的这些“孤儿进程”(orphan process),而这些“孤儿进程”执行完后,它在进程表中的进入点将被删除。如果一个程序设计上有缺陷,就可能导致某个进程的父进程一直处于睡眠状态或是陷入死循环,父进程没有wait子进程,也没有终止以使Init接管,该子进程执行结束后就变成了defunct进程,这个defunct 进程可能会一直留在系统中直到系统重新启动。

在看一个产生僵尸进程的例子。

子进程要执行的程序test_prog

//test.c 
#include <stdio.h> int main()  {  
 int i = 0;  
 for (i = 0 ; i </stdio.h>

父进程father的代码father.c

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
int main()  
{  
 int pid = fork ();  
 if (pid == 0)  
        {  
                system ("./test_prog");  
                _exit (0);  
        }else 
        {  
 int i = 0;  
 /* 
                                int status = 0; 
                while (!waitpid(pid, &status, WNOHANG)) 
                { 
                        printf ("father waiting%d\n", ++i); 
                        sleep (1); 
                }*/ 
 while (1)  
                {  
                        printf ("father waiting over%d\n", ++i);  
                        sleep (1);  
                }  
 return 0;  
        }  
 
}

执行./father,当子进程退出后,由于父进程没有对它的退出进行关注,会出现僵尸进程

20786 pts/0    00:00:00 father  
20787 pts/0    00:00:00 father <defunct></defunct>

总结:子进程成为 defunct 直到父进程 wait(),除非父进程忽略了 SIGCLD 。更进一步,父进程没有 wait() 就消亡(仍假设父进程没有忽略 SIGCLD )的子进程(活动的或者 defunct)成为 init 的子进程,init 着手处理它们。

五、如何避免僵尸进程

1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。

在上个例子中,如果我们略作修改,在第8行sleep()系统调用前执行wait()或waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。

2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler。在子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。

3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCLD, SIG_IGN)或signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号

4. fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。 下面就是Stevens给的采用两次folk避免僵尸进程的示例:

#include "apue.h" #include <sys>  int main(void)  ...{  
     pid_t    pid;  
 
 if ((pid = fork())  0)  
             exit(0);    /**//* parent from second fork == first child */ 
 /**//* 
          * We're the second child; our parent becomes init as soon 
          * as our real parent calls exit() in the statement above. 
          * Here's where we'd continue executing, knowing that when 
          * we're done, init will reap our status. 
         */ 
         sleep(2);  
         printf("second child, parent pid = %d ", getppid());  
         exit(0);  
     }  
 
 if (waitpid(pid, NULL, 0) != pid)  /**//* wait for first child */ 
         err_sys("waitpid error");  
 
 /**//* 
      * We're the parent (the original process); we continue executing, 
      * knowing that we're not the parent of the second child. 
     */ 
     exit(0);  }</sys>

相关推荐:《Linux视频教程

以上是linux 殭屍行程是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
掌握Linux操作:實用指南掌握Linux操作:實用指南Apr 12, 2025 am 12:10 AM

掌握Linux操作的原因是其廣泛的應用場景和強大的功能。 1)Linux適合開發者、系統管理員和技術愛好者,應用於服務器管理、嵌入式系統和容器化技術。 2)學習Linux可以從文件系統結構、Shell使用、用戶權限管理和進程管理入手。 3)Linux命令行是其核心工具,通過Shell執行命令,如ls、mkdir、cd等,支持重定向和管道操作。 4)高級用法包括編寫自動化腳本,如備份腳本,使用tar命令和條件判斷。 5)常見錯誤包括權限、路徑和語法問題,可通過echo、set-x和$?調試。 6)性能優化建議

Linux的5支支柱:了解他們的角色Linux的5支支柱:了解他們的角色Apr 11, 2025 am 12:07 AM

Linux系統的五大支柱是:1.內核,2.系統庫,3.Shell,4.文件系統,5.系統工具。內核管理硬件資源並提供基本服務;系統庫為應用程序提供預編譯函數;Shell是用戶與系統交互的接口;文件系統組織和存儲數據;系統工具用於系統管理和維護。

Linux維護模式:工具和技術Linux維護模式:工具和技術Apr 10, 2025 am 09:42 AM

在Linux系統中,可以通過在啟動時按特定鍵或使用命令如“sudosystemctlrescue”進入維護模式。維護模式允許管理員在不受干擾的情況下進行系統維護和故障排除,如修復文件系統、重置密碼、修補安全漏洞等。

關鍵Linux操作:初學者指南關鍵Linux操作:初學者指南Apr 09, 2025 pm 04:09 PM

Linux初學者應掌握文件管理、用戶管理和網絡配置等基本操作。 1)文件管理:使用mkdir、touch、ls、rm、mv、cp命令。 2)用戶管理:使用useradd、passwd、userdel、usermod命令。 3)網絡配置:使用ifconfig、echo、ufw命令。這些操作是Linux系統管理的基礎,熟練掌握它們可以有效管理系統。

如何使用sudo向Linux的用戶授予高架特權?如何使用sudo向Linux的用戶授予高架特權?Mar 17, 2025 pm 05:32 PM

本文解釋瞭如何管理Linux中的Sudo特權,包括授予,撤銷和安全性最佳實踐。關鍵重點是安全和sudoers安全和限制訪問。Character數量:159

如何在Linux中實現SSH的兩因素身份驗證(2FA)?如何在Linux中實現SSH的兩因素身份驗證(2FA)?Mar 17, 2025 pm 05:31 PM

本文提供了有關使用Google Authenticator在Linux上設置兩因素身份驗證(2FA)的指南,詳細介紹了安裝,配置和故障排除步驟。它突出了2FA的安全益處,例如增強的SEC

如何使用TOP,HTOP和VMSTAT等工具來監視Linux中的系統性能?如何使用TOP,HTOP和VMSTAT等工具來監視Linux中的系統性能?Mar 17, 2025 pm 05:28 PM

本文討論了使用TOP,HTOP和VMSTAT監視Linux系統性能,並詳細介紹其獨特功能和自定義選項,以進行有效的系統管理。

如何使用軟件包管理器(APT,YUM,DNF)管理Linux中的軟件包?如何使用軟件包管理器(APT,YUM,DNF)管理Linux中的軟件包?Mar 17, 2025 pm 05:26 PM

文章討論了使用APT,YUM和DNF在Linux中管理軟件包,涵蓋安裝,更新和刪除。它比較了它們對不同分佈的功能和適用性。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

將Eclipse與SAP NetWeaver應用伺服器整合。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具