sharjeel
sharjeel

Reputation: 6005

Perl fork(), exec() and then kill creating zombie process

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

Answers (2)

Dave Sherohman
Dave Sherohman

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

user1149862
user1149862

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

Related Questions