Windows中的Perl kill(0,$pid)始终返回1

Windows中的Perl kill(0,$pid)始终返回1,windows,perl,process,Windows,Perl,Process,我正在尝试制作一个Perl脚本,它将在Windows中运行一组其他程序。我需要能够捕获进程的stdout、stderr和exit代码,并且我需要能够查看一个进程是否超过了它分配的执行时间。 现在,我的代码的相关部分如下所示: ... $pid = open3($wtr, $stdout, $stderr, $command); if($time < 0){ waitpid($pid, 0); $return =

我正在尝试制作一个Perl脚本,它将在Windows中运行一组其他程序。我需要能够捕获进程的stdout、stderr和exit代码,并且我需要能够查看一个进程是否超过了它分配的执行时间。 现在,我的代码的相关部分如下所示:

...
        $pid = open3($wtr, $stdout, $stderr, $command);
        if($time < 0){
            waitpid($pid, 0);
            $return = $? >> 8;
            $death_sig = $? & 127;
            $core_dump = $? & 128;
        }
        else{
            # Do timeout stuff, currently not working as planned
            print "pid: $pid\n";
            my $elapsed = 0;
            #THIS LOOP ONLY TERMINATES WHEN $time > $elapsed ...?
            while(kill 0, $pid and $time > $elapsed){
                Time::HiRes::usleep(1000);  # sleep for milliseconds
                $elapsed += 1;
                $return = $? >> 8;
                $death_sig = $? & 127;
                $core_dump = $? & 128;
            }
            if($elapsed >= $time){
                $status = "FAIL";
                print $log "TIME LIMIT EXCEEDED\n";
            }
        }
        #these lines are needed to grab the stdout and stderr in arrays so 
        #  I may reuse them in multiple logs
        if(fileno $stdout){
            @stdout = <$stdout>;
        }
        if(fileno $stderr){
            @stderr = <$stderr>;
        }
...

使用以下命令而不是
kill 0


使用以下命令而不是
kill 0


Windows没有信号。也许你不应该用它们来判断进程是否正在运行。kill-返回成功发送信号的进程数(不一定与实际被杀死的进程数相同)。@ikegami说Win32实现了
kill(0,…)
semantics.huh?您可以
waitpid
。实际上,你为什么要起诉杀戮?为什么不使用nohang
waitpid
?更新中的代码问题:即使不使用
waitpid
,也可以访问
$?
(因此它包含垃圾)。如果子对象在其标准输出上填充管道的缓冲区,则会发生死锁。STDERR也是如此。(这些死锁将导致“假”超时。)您不会在超时时杀死子级。你应该使用。Windows没有信号。也许你不应该用它们来判断进程是否正在运行。kill-返回成功发送信号的进程数(不一定与实际被杀死的进程数相同)。@ikegami说Win32实现了
kill(0,…)
semantics.huh?您可以
waitpid
。实际上,你为什么要起诉杀戮?为什么不使用nohang
waitpid
?更新中的代码问题:即使不使用
waitpid
,也可以访问
$?
(因此它包含垃圾)。如果子对象在其标准输出上填充管道的缓冲区,则会发生死锁。STDERR也是如此。(这些死锁将导致“假”超时。)您不会在超时时杀死子级。你应该使用。
        $pid = open3($wtr, $stdout, $stderr, $command);
        close($wtr);
        if($time < 0){
            waitpid($pid, 0);
        }
        else{
            print "pid: $pid\n";
            my $elapsed = 0;
            while(waitpid($pid, WNOHANG) <= 0 and $time > $elapsed){
                Time::HiRes::usleep(1000);  # sleep for milliseconds
                $elapsed += 1;
            }

            if($elapsed >= $time){
                $status = "FAIL";
                print $log "TIME LIMIT EXCEEDED\n";
            }
        }
        $return = $? >> 8;
        $death_sig = $? & 127;
        $core_dump = $? & 128;
        if(fileno $stdout){
            @stdout = <$stdout>;
        }
        if(fileno $stderr){
            @stderr = <$stderr>;
        }
        close($stdout);
        close($stderr);
use POSIX qw( WHOHANG );

if (waitpid($pid, WNOHANG) > 0) {
   # Process has ended. $? is set.
   ...
}