2013-03-19 125 views
0

我試圖在fork中使用perl,exec來啓動android模擬器。之後我需要殺死它,但是殺死它會導致仿真程序在後臺運行的殭屍進程。Perl fork(),exec()然後殺死創建殭屍進程

我試過用kill -1以及kill -9killall -v emulator來查殺。我也嘗試通過附加顯式exec(「exec command ...」)來執行exec'ing,但是無論哪種方式,我都會得到一個殭屍進程,直到perl腳本運行。

這裏是我的代碼:

my $CMD; 
my $PID; 

sub waitkey() 
{ 
    local($|) = (1); 
    print "Press <Enter> or <Return> to continue: "; 
    my $resp = <STDIN>; 
} 


$|++; 

$CMD = "emulator -avd audit -no-snapshot-save"; 
# $CMD = "exec emulator -avd audit -no-snapshot-save"; 

$PID = fork(); 
if ($PID==0) 
{ 
    print "forked!\n\n"; 
    sleep(1); 
    exec("$CMD"); 
    die "Unable to execute"; 
} 

print "PID: $PID\n\n"; 

sleep(1); 
print "------ Processes before killing -----\n"; 
print `ps aux | grep emulator`; 
print "------ Press a key to kill -----\n\n" 

&waitkey; 
# `kill -1 $PID`; 
`kill -9 $PID`; 

print "------ Processes after killing -----\n"; 
sleep(1); 
print `ps aux | grep emulator`; 


print "----- waiting ... -----\n"; 
#-- do somehing here with assumption that emulator has been killed -- 
&waitkey; 

在輸出我看到

------ Processes before killing ----- 
qureshi 10561 0.0 0.0 3556 980 pts/5 S+ 13:28 0:00 emulator -avd audit -no-snapshot-save 
qureshi 10562 0.0 0.0 4396 616 pts/5 S+ 13:28 0:00 sh -c ps aux | grep emulator 
qureshi 10564 0.0 0.0 13580 928 pts/5 S+ 13:28 0:00 grep emulator 

並殺害的過程

------ Processes after killing ----- 
qureshi 10561 30.0 0.0  0  0 pts/5 R+ 13:28 0:01 [emulator64-arm] 
qureshi 10619 0.0 0.0 4396 612 pts/5 S+ 13:28 0:00 sh -c ps aux | grep emulator 
qureshi 10621 0.0 0.0 13580 932 pts/5 S+ 13:28 0:00 grep emulator 

如何擺脫殭屍進程後?

回答

4

在殺死子進程後,您應該在父進程中使用waitpid。那是因爲你使用fork來獲得一個新的進程,Perl不會爲你做如system那樣的清理工作。 但是我建議在CPAN中做a better module,這樣做是非常麻煩的事情,我覺得非常方便。

5

殭屍只是一個進程表條目,它正在等待父進程前來並收集其退出狀態。正如perldoc fork不會對你的孩子永遠等待如果您叉記載,

,你會積累 殭屍。在某些系統上,您可以通過將$ SIG {CHLD}設置爲 「IGNORE」來避免此情況。

設置$SIG{CHLD}適用於包括Linux在內的大多數Unix系統,因此這將是安排您的孩子安心休息的最簡單方式。

順便提一下,用&前綴調用用戶定義的函數是一個Perl 4主題。在當前的Perl版本中,您應該只使用waitkeywaitkey()而不是&waitkey