Perl fork(),exec()然后杀死创建僵尸进程

问题描述:

我试图在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 

如何摆脱僵尸进程后?

在杀死子进程后,您应该在父进程中使用waitpid。那是因为你使用fork来获得一个新的进程,Perl不会为你做如system那样的清理工作。 但是我建议在CPAN中做a better module,这样做是非常麻烦的事情,我觉得非常方便。

僵尸只是一个进程表条目,它正在等待父进程前来并收集其退出状态。正如perldoc fork不会对你的孩子永远等待如果您叉记载,

,你会积累 僵尸。在某些系统上,您可以通过将$ SIG {CHLD}设置为 “IGNORE”来避免此情况。

设置$SIG{CHLD}适用于包括Linux在内的大多数Unix系统,因此这将是安排您的孩子安心休息的最简单方式。

顺便提一下,用&前缀调用用户定义的函数是一个Perl 4主题。在当前的Perl版本中,您应该只使用waitkeywaitkey()而不是&waitkey