fork子程序殭屍問題及解決方案

2021-07-22 13:16:20 字數 1913 閱讀 2459

原來用 c 寫 cgi 的時候用過 fork 。那時候 cgi 的生命很短,所以遇到的問題壓根沒出現過。這次也是更加深入的對 fork 機制進行了一下了解。

參考這裡的文件:

1. 我們都是小殭屍

下面是這次應用的乙個 fork 的例子。主程序繼續進行資料處理,一定時間後用下面的**開新程序,並將處理結果傳送出去。看起來似乎沒什麼問題,但是,一定時間後,fork 總是failed。。。用 ps aux 檢視程序列表,列表被殭屍程序佔滿了!!

...

if ((pid=fork())<0

)

else

if ( 0 ==pid)

...

好吧,難道 exit(0) 之後,它還在留戀什麼?所以,又回來繼續摸索什麼是最有可能性。

2. 小殭屍找爸爸

好吧,最後目光落到了這裡 sigchld。通常,父程序不會始終處於等待狀態,它還需要執行其它**,因此「等待」的工作會使用訊號機制來完成;或者說,子程序在處理完任務以後,核心會傳送乙個sigchld訊號。。。對,這孩子還要向它爸做最後的告別。

那孩它爸能做些什麼呢?

1)孩它爸也不在了。

2)孩它爸在等待關於這孩子的訊息,完成告別儀式,各安天命。

3)孩它爸發布了告示「我沒有兒子,你們都別來煩我」。

恩,第乙個這是肯定的,因為fork機制天生的屬性,如果孩它爸不在了,它會被送給init來監管撫養。。。init是個負責任的好爸爸,他會處理好一切。那接下來兩個是怎麼回事呢?

3.小殭屍和爸爸最後的告別

用於監督子程序的完成情況,fork配套使用的有waitpid()和wait()兩個函式。waitpid()的功能和wait()類似,但waitpid()提供了額外的選項(wait(null)等價於waitpid(-1, null, 0))。如,wait()函式是阻塞的,而waitpid()提供了wnohang選項,呼叫後會立刻返回,可根據返回值判斷等待結果。

#include #include 

#include

#include

#include

#include

#include

#include

in.h>#include

#include

#include

void signal_handler(int

signo)

}}void mysleep(int

sec)

}int main(int argc, char **argv)

else

if (pid == 0

) else}}

比如上面的**。我們在訊號處理中使用了乙個迴圈體,不斷呼叫waitpid(),直到失敗為止。那是因為在系統繁忙時,訊號可能會被合併,即兩個子程序結束只會傳送一次sigchld訊號,如果只wait()一次,就會產生殭屍程序。(由於預設的sleep()函式會在接收到訊號時立即返回,因此為了方便演示,這裡定義了mysleep()函式)。

4.做個不負責任的爸爸

很簡單,用下面這句話,告訴作業系統,你不關心所有那些子程序的死活。

signal(sigchld, sig_ign);
但是,這樣做的問題是,有些bsd系統不支援這樣的用法。所以,更為廣泛的,還是使用wait。

perl中

下面是perl中使用fork-waitpid的**,也是也不是我寫的:

#!/usr/bin/perl

sub reaper

}$sig = \&reaper;

my $pid =fork();

if ($pid > 0

) elsif ($pid == 0

)

這個和c基本一樣的。如果想要忽略sigchld,可使用$sig = 'ignore'。

fork子程序殭屍問題及解決方案

額,原來用 c 寫 cgi 的時候用過 fork 那時候 cgi 的生命很短,所以遇到的問題壓根沒出現過。這次也是更加深入的對 fork 機制進行了一下了解。1.我們都是小殭屍 下面是這次應用的乙個 fork 的例子。主程序繼續進行資料處理,一定時間後用下面的 開新程序,並將處理結果傳送出去。看起來...

fork兩次解決殭屍程序

孤兒程序 孤兒程序是指父程序在子程序結束之前死亡 return 或exit 如下圖1所示 圖1 孤兒程序 但是孤兒程序並不會像上面畫的那樣持續很長時間,當系統發現孤兒程序時,init程序就收養孤兒程序,成為它的父親,child程序exit後的資源 就都由init程序來完成。殭屍程序 殭屍程序是指子程...

Linux環境下殭屍程序產生原因及解決方法

1.產生原因 在unix 系統中,乙個程序結束了,但是他的父程序沒有等待 呼叫wait waitpid 他,那麼他將變成乙個殭屍程序。通過ps命令檢視其帶有defunct的標誌。殭屍程序是乙個早已死亡的程序,但在程序表 processs table 中仍佔了乙個位置 slot 但是如果該程序的父程序...