以下设置:
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;没有成功。
答案 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.