Apparently those processes are not zombies. You'll need to kill the tcpdump process when the alarm goes off, and in order to do that you'll need to know its pid.
Actually, I think I'd use a different approach:
my $pid = open(T, "tcpdump ...|");
eval {
while (1) {
$SIG{ALRM} = sub { die "time to stop" }
alarm(20);
my $line = <T>; # read a line from tcpdump
alarm(0);
last unless defined($line);
# process line
}
};
kill 9, $pid;
close(T);
Or, you can use IO::Select:
my $pid = open my $T, "tcpdump ...|";
my $sel = new IO::Select($T);
my $buf;
while ($sel->can_read($T, 20)) {
read($T, $buf, 1024, length($buf)) or last;
}
kill 9, $pid;
close($T);
# $buf contains output from tcpdump
|