殭屍程序的處理辦法
殭屍程序(僵死程序)是指一個程序主體結束,但是該程序的PCB依舊存在的情況或者在多程序程式設計中,父程序未結束但是子程序已經結束父程序沒有對子程序進行回收。
殭屍程序存在的意義在於程序結束後,程序的退出狀態需要儲存到PCB結構中,方便父程序獲取子程序的退出狀態。
程序真正結束的標誌:1、程序主體退出。2、父程序獲取子程序的退出狀態之後,子程序的PCB釋放。
那麼我們為什麼要處理掉殭屍程序呢,這是因為子程序結束完畢之後,別的空間都釋放掉了,但是記錄子程序的PCB還存在,長此以往,大量的PCB佔用空間,就會造成空間浪費,甚至造成記憶體不足,所以在子程序結束後我們要將它徹底清除掉。我們可以考慮在當子程序結束時,通知父程序來處理這個結束的子程序。那麼父程序是如何獲取子程序的退出狀態來處理該程序呢?
這就要用到wait函式來為子程序“收屍了”。
wait()的函式原型是:
#include
#include
pid_t wait(int *status)
父程序一旦呼叫了wait函式,就立即阻塞自己,由wait自動分析是否當前程序的某個子程序已經退出,如果讓它找到了這樣一個已經變成殭屍的子程序,wait()就會收集這個子程序的資訊,並把它徹底銷燬後返回;如果沒有找到這樣一個子程序,wait就會一直阻塞在這裡,直到有一個出現為止。
wait()函式的引數:
引數status用來儲存被收集程序退出時的一些狀態,它是一個指向int型別的指標。但如果我們對這個子程序是如何死掉的毫不在意,只想把這個殭屍程序消滅掉,我們就可以設定這個引數為NULL,就象下面這樣:
pid = wait(NULL);
但是這個時候我們就又遇到了一個問題:如果子程序無限迴圈或者執行時間需要很久,那麼呼叫wait函式,我們豈不是要浪費很大的時間,所以我們就在想,能不能同時執行父子程序,當子程序結束後以一種特定的方式通知父程序。這種方式就相當於子程序結束後給父程序傳送一個訊號,父程序接收到訊號後停下來,來處理訊號所對應的函式,處理完之後在回來繼續執行,我們就可以在訊號對應的函式中將子程序結束掉。
所以我們要用到SIGCHLD訊號處理函式,原型為
signal(int SIGCHLD,void (*fun)(int))
可以在fun函式裡實現接收到子程序結束訊號後子程序的結束。即給訊號繫結一個訊號處理函式,當程序接收到訊號後,回撥訊號處理函式。這樣在處理殭屍程序的過程中就不用花費大量時間等待了。