Python腳本模擬僵屍進程與孤兒進程


最近一台機器的systemd內存高達30%多,一直不變,后來排查是僵屍進程,什么是僵屍進程呢,只能google,百度等先了解,然后自己總結了一下,雖然這是基礎的東西,但是對於我來說就如新大陸一樣。花了一下午可算明白了。模擬的時候主要是先要理解fork這個函數的東西。總結的不對的地方望給位大哥指出
 
什么是僵屍進程?什么是孤兒進程?
 
僵屍進程:一個進程使用fork() 創建子進程,如果子進程退出,而父進程並沒有調用wait或waitpid獲取子進程的狀態信息,那么子進程的進程描述符仍然保存在系統中,這種進程稱之為僵屍進程
 
孤兒進程:一個父進程退出,而它的一個或多個子進程還在運行,那么這些進程將會成為孤兒進程。孤兒進程將會被init進程(進程號為1)所收養,並由init進程對他們完成狀態收集工作
 
模擬僵屍進程和孤兒進程
 
1:使用os.fork()之后,子進程是父進程的復制品,在內存中會把父進程的代碼及內存分配情況拷貝一份生成子進程的運行空間,這樣子進程與父進程的所有代碼都一樣,兩個進程之間的運行時獨立的,互不影響。在父進程中獲取到的pid是子進程的pid號,在子進程中獲取的pid是0.
 
python腳本:
#!/usr/bin/python

import os,sys,time

pid = os.fork()

if pid == 0:
    print "this is child pid=",pid
else:
    print "This is parent pid=",pid

 

在執行上面這段代碼的時候,會有兩個獨立的運行空間獨立的代碼來執行,在父進程中執行的時候,由於返回的是子進程的pid,所以不會等於0,就走else。
在子進程的獨立的運行空間執行上面的那份代碼,因為fork給子進程返回的是0,所以就走if那條。
 
執行結果:
 
fork()函數被調用一次,返回兩次。兩次返回的區別是子進程的返回值是0,而父進程的返回值則是新子進程的進程ID
 
2: getpid(),petppid()  
os.getpid() 獲取的是當前進程的進程號
os.getppid() 獲取當前進程的父進程的進程號
 
python腳本:
#!/usr/bin/python

import os,sys,time

pid = os.fork()
getpid = os.getpid()
getppid = os.getppid()

if pid == 0:
    print "this is child pid=%d,getpid=%d,getppid=%d" %(pid,getpid,getppid)
else:
    print "This is parent pid=%d,getpid=%d,getppid=%d"%(pid,getpid,getppid)

 

執行結果:
 
這里為什么子進程的父進程PID是1呢,而不是創建它的父進程ID104809呢,這問題就是上面孤兒進程現象了,看上面的輸出結果可以看到,父進程先執行完,后執行的子進程,這就意味着,子進程執行完了的時候,父進程已經不在了,就成了孤兒進程,孤兒進程最終會由init,也就是進程1收養,把它殺掉
 
3:模擬僵屍進程
 
python腳本:
#!/usr/bin/python

import os,sys,time

pid = os.fork()
getpid = os.getpid()
getppid = os.getppid()

if pid == 0:
    print "this is child pid=%d,getpid=%d,getppid=%d" %(pid,getpid,getppid)
else:
    print "This is parent pid=%d,getpid=%d,getppid=%d"%(pid,getpid,getppid)
    time.sleep(10)

 

執行結果:
 
這里可以看到子進程的父進程pid確實是創建自己的父進程,但是子進程已經成了僵屍進程,通過top命令或者grep def查看
 
 
子進程成了僵屍進程是因為子進程結束的時候,父進程還在睡覺,不能調用wait()或waitpid()去獲取子進程的終止狀態,但是等父進程醒來的時候,就會把僵屍進程給處理掉
 
4:真實環境下僵屍進程產生了怎么解決
 
      暫時知道的辦法是:根據僵屍進程找出僵屍進程的父進程,通過殺父進程的方式刪掉僵屍進程,但是線上環境不要輕易刪父進程
      常用的命令有:
      ps -ef |grep def                                查看僵屍進程   
      ps -e -o pid,stat |grep Z                   查看僵屍進程的pid
      ps -e -o ppid,stat |grep Z                 查看僵屍進程的父進程
      
5:如何避免僵屍進程的產生
      這還有待研究
 
 
參考博文及書籍
《UNIX環境高級編程中文版》
下載地址:https://pan.baidu.com/s/1mios8Wg 密碼:zlig


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM