perl filehandle while循环不会在没有其他行的情况下终止

时间:2016-07-13 11:13:48

标签: perl while-loop file-handling

以下设置:

linux debian based 4.4.14-v7+ armv7l GNU/Linux
perl version is v5.20.2 built for arm-linux-gnueabihf-thread-multi-64int

应该读取数据流的Perl脚本(十六进制字符,每行不同长度) 示例流输出:

00 AA BB 11 22 33 44 ...
00 AB BB 11 22 33 44 ...

根据具体值,脚本应执行特定操作。 工作正常但是当流停止发送数据时,即流完成发送数据时,while循环不会停止。并且脚本等待更多行。

流本身发送f.e. 5秒的数据,然后分析脚本应该do_stuff;

一旦分析脚本完成计算,它将再次启动流。

但是我无法弄清楚为什么" next命令"未执行,或者while循环没有在没有其他行的情况下正确终止。

如果我再次手动启动流处理,则分析脚本会继续正常,直到再没有其他行为止。

简化代码

#!/usr/bin/perl
#script to analyse data
use warnings;
use strict;
use POSIX ();

sub stop_stream($){
  my $pid = shift;
  my $cmd = "/bin/kill -9 $pid";
  system($cmd);
}

while (1){

my $steampid = open( STREAM, "/usr/local/bin/stream |" );

STREAM: while ( my $row = <STREAM> ) {
chomp $row;
my @o = split /\s+/, $row;

#do_stuff;
#..
#this is the row on which the script hangs until it get's new lines in the filehandle.
next STREAM if $o[1] ne "AA";
#...
#do_other_stuff;
#...
}

stop_stream( $steampid );
close STREAM;

}

资源我试图弄清楚问题:

http://perldoc.perl.org/perlsyn.html#Compound-Statements

http://www.perlmonks.org/?node_id=1065701

和其他许多人。

我尝试使用&#34; perl的一些组合进行stackoverflow,同时循环关闭文件句柄&#34;没有成功。

1 个答案:

答案 0 :(得分:3)

好的,问题的根源在于,如果文件句柄打开while ( <FILEHANDLE> ) {循环将阻止,但没有数据可供读取。

因此/usr/local/bin/stream可能会继续管道数据直到被杀 - 所以你的读取阻塞了。

简单的解决方案是使用IO::Select之类的can_read作为选项:

use IO::Select;
open ( my $stream, '-|', '/usr/local/bin/stream' ) or die $!; 
#register this filehandle with a new select object
my $select = IO::Select -> new ( $stream );

#2s stream timeout. 
#works because can_read returns a list of filehandles ready for reading
#with only one filehandle registered, it can be used as a simple logic test. 
while ( $select -> can_read(2) ) { 
    my $row = <$stream>; 
    #etc. 
}

#etc.