簡體   English   中英

Windows中的Perl kill(0,$ pid)總是返回1

[英]Perl kill(0, $pid) in Windows always returning 1

我正在嘗試制作一個Perl腳本,該腳本將在Windows中運行一組其他程序。 我需要能夠捕獲進程的stdout,stderr和退出代碼,並且我必須能夠查看進程是否超過了分配的執行時間。 現在,我的代碼的相關部分如下所示:

...
        $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>;
        }
...

如果$time = -1 (不需要超時),則一切工作正常,但是系統認為kill 0, $pid始終為1。這使我的循環在允許的整個時間內運行。

一些額外的細節只是為了清楚起見:

  • 它正在Windows上運行。
  • 我知道我的過程確實會終止,因為我已經獲得了所有預期的輸出。
  • Perl版本:這是MSWin32 86多線程構建的perl,v5.10.1(2個注冊補丁,看到的perl-V的更詳細)版權所有1987-2011,Larry Wall的二進制建1007 [291969]由ActiveState公司提供的HTTP ://www.ActiveState.com內置2010年1月26日23:15:11
  • 感謝您的幫助:D

對於可能遇到類似問題的將來的人,我讓代碼可以工作,這是修改后的代碼部分:

        $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);

代替kill 0 ,使用waitpid $pid, WNOHANG

use POSIX qw( WHOHANG );

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM