Kill a hung child process

前端 未结 3 1855
醉酒成梦
醉酒成梦 2021-01-13 09:38

My Perl script runs an external program (which takes a single command-line parameter) and processes its output. Originally, I was doing this:

my @result = `p         


        
3条回答
  •  孤城傲影
    2021-01-13 09:55

    This is the best I could do. Any ideas on how to avoid the use of a temporary file on Windows would be appreciated.

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use File::Temp;
    use Win32::Process qw(STILL_ACTIVE NORMAL_PRIORITY_CLASS);
    
    my $pid;
    my $timeout = 10;
    my $prog = "prog arg";
    my @output;
    
    if ($^O eq "MSWin32")
    {
        my $exitcode;
        my $fh = File::Temp->new ();
        my $output_file = $fh->filename;
        close ($fh);
        open (OLDOUT, ">&STDOUT");
        open (STDOUT, ">$output_file" ) || die ("Unable to redirect STDOUT to $output_file.\n");
        Win32::Process::Create ($pid, $^X, $prog, 1, NORMAL_PRIORITY_CLASS, '.') or die Win32::FormatMessage (Win32::GetLastError ());
        for (1 .. $timeout)
        {
            $pid->GetExitCode ($exitcode);
            last if ($exitcode != STILL_ACTIVE);
            sleep 1;
        }
        $pid->GetExitCode ($exitcode);
        $pid->Kill (0) or die "Cannot kill '$pid'" if ($exitcode == STILL_ACTIVE);
        close (STDOUT);
        open (STDOUT, ">&OLDOUT");
        close (OLDOUT);
        open (FILE, "<$output_file");
        push @output, $_ while ();
        close (FILE);
    }
    else
    {
        $pid = open my $proc, "-|", $prog;
        exec ($^X, "-e", "sleep 1, kill (0, $pid) || exit for 1..$timeout; kill -9, $pid") unless (fork ());
        push @output, $_ while (<$proc>);
        close ($proc);
    }
    print "Output:\n";
    print @output;
    

提交回复
热议问题