rovf has asked for the wisdom of the Perl Monks concerning the following question:

What is the proper way to kill on Windows a process which has been started with a forked Windows call, i.e. system(1,...)? I'm trying the following:

my $pid=system(1,"my_prog.bat"); ... if(kill(9,$pid)) { print "Killing $pid was not successful\n" if kill(0,$pid); } else { print "Signal did not reach process $pid\n"; }
I always get "Killing ... was not successful".

I know that the process is still running at the time the first kill is issued. The purpose of the second kill (with 0 zero) is to ensure that the process really got killed. If it was, kill should return 0 (no such process), but it returns non-zero, showing that the process still lives. Indeed, I can see from the output that the "killed" process happily runs to the end.
-- 
Ronald Fischer <ynnor@mm.st>

Replies are listed 'Best First'.
Re: Killing on Windows
by ikegami (Patriarch) on Sep 09, 2009 at 14:44 UTC

    You're being told the process still exists, which it will until all handles to it have been closed. In unix parlance, the child is zombie at that point. Processes exist in that state in order to allow their parent to collect their exit code. wait and waitpid collect the exit code and close the handle.

    my $pid = system(1, $^X, -e => 'sleep 30 while 1') or die("system,1: $!\n"); kill(9, $pid) or die("kill: $!\n"); if (kill(0, $pid)) { print("Process $pid still exists\n") ; } else { print("kill 0: $!\n") ; } waitpid($pid, 0) or die("waitpid: $!\n"); if (kill(0, $pid)) { print("Process $pid still exists\n") ; } else { print("kill 0: $!\n") ; }
    Process 4912 still exists kill 0: Invalid argument

      Thanks for the explanation. I now see that my real problem is that the kill of course kill only the process directly invoked; but that process had at this time already invoked other child processes, and *they* are of course not killed, and they run to the end.

      What possibilities exist in Windows to kill a process *including* all of its children in one go? On Solaris, I would use pkill. I think this is such a common problem that there is likely also something available for Windows...

      -- 
      Ronald Fischer <ynnor@mm.st>
        What possibilities exist in Windows to kill a process *including* all of its children in one go?

        See Win32::Job.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.