Reputation: 6005
I am trying to launch android emulator in perl using fork, exec. Afterwards I need to kill it too but killing it results in zombie processes with emulator running in background.
I've tried killing using kill -1
as well as kill -9
and killall -v emulator
. I've also tried exec'ing by appending explicit exec("exec command ...") but either way I get a zombie process till the perl script is running.
Here is my code:
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;
In the output I see
------ 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
and after killing the process
------ 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
How do I get rid of the Zombie process?
Upvotes: 0
Views: 4938
Reputation: 46187
A zombie is just a process table entry that's waiting for the parent process to come by and collect its exit status. As documented in perldoc fork,
If you fork without ever waiting on your children, you will accumulate zombies. On some systems, you can avoid this by setting $SIG{CHLD} to "IGNORE" .
Setting $SIG{CHLD}
works on most unix-type systems, including Linux, so that would be the easiest way to arrange for your children to rest in peace.
BTW, calling user-defined functions with the &
prefix is a Perl 4-ism. In current Perl versions, you should use just waitkey
or waitkey()
instead of &waitkey
.
Upvotes: 5
Reputation:
You should use waitpid
in parent process after killing the child process. That's because you use fork
to get a new process, Perl wouldn't do the clean-up job for you as in system
.
But I recommend a better module in CPAN which does the whole messy thing, I find it very convenient.
Upvotes: 4