[英]Perl fork(), exec() and then kill creating zombie process
我正在嘗試使用fork,exec在perl中啟動android模擬器。 之后,我也需要殺死它,但是殺死它會導致在后台運行模擬器的僵屍進程。
我試過使用kill -1
以及kill -9
和killall -v emulator
kill -9
。 我還嘗試通過附加顯式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
如何擺脫僵屍進程?
僵屍只是一個進程表條目,它在等待父進程通過並收集其退出狀態。 如perldoc fork中所述 ,
如果您在沒有等待孩子的情況下進行分叉,則會堆積僵屍。 在某些系統上,可以通過將$ SIG {CHLD}設置為“ IGNORE”來避免這種情況。
設置$SIG{CHLD}
可以在包括Linux在內的大多數unix型系統上使用,因此這是安排孩子安息的最簡單方法。
順便說一句,用&
前綴調用用戶定義的函數是一種Perl 4主義。 在當前的Perl版本中,應僅使用waitkey
或waitkey()
而不是&waitkey
。
殺死子進程后,應在父進程中使用waitpid
。 那是因為您使用fork
獲得了一個新進程,Perl不會像system
那樣為您完成清理工作。 但是我建議在CPAN中使用一個更好的模塊來完成整個工作,我發現它非常方便。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.