Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
perl filehandle while循环不会在没有其他行的情况下终止_Perl_While Loop_File Handling - Fatal编程技术网

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

perl filehandle while循环不会在没有其他行的情况下终止,perl,while-loop,file-handling,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 ... 根据特定的值,脚本应该执行特定的操作。 工作正常,但是当流停止发送数据

以下设置:

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秒的数据,然后分析脚本应该做一些事情

分析脚本完成计算后,将再次启动流

但是,我无法理解为什么“下一个命令”没有执行,或者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;

}
#/usr/bin/perl
#用于分析数据的脚本
使用警告;
严格使用;
使用POSIX();
子站\u流(美元){
我的$pid=班次;
my$cmd=“/bin/kill-9$pid”;
系统(cmd);
}
而(1){
my$steampid=open(STREAM,“/usr/local/bin/STREAM |”);
流:while(我的$row=){
咀嚼$row;
my@o=split/\s+/,$row;
#做事;
#..
#这是脚本挂起的行,直到它在文件句柄中获得新的行。
如果$o[1]ne“AA”,则为下一个流;
#...
#做其他事情;
#...
}
停止流动($steampid);
近流;
}
参考资料我试图找出问题所在:

还有很多其他的


我尝试将stackoverflow与“perl while loop close filehandle”结合使用,但没有成功。

好的,这里的问题的根源是
while(){
循环将在文件句柄打开但没有要读取的数据时阻塞

因此,
/usr/local/bin/stream
很可能会继续管道数据,直到终止,所以您的读取块

简单的解决方案是使用类似has
can\u 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. 
使用IO::Select;
打开(我的$stream,'-|','/usr/local/bin/stream')或死$!;
#使用新的选择对象注册此文件句柄
我的$select=IO::select->new($stream);
#2s流超时。
#因为can_read返回一个准备读取的文件句柄列表
#由于只注册了一个filehandle,因此它可以用作简单的逻辑测试。
而($select->can_read(2)){
我的$row=;
#等等。
}
#等等。

重新使用“流”以不同的方式似乎是在自找麻烦。流的结尾是如何发出信号的?它是以文件结尾结束的,还是管道关闭的,还是…?进程流将通过sigkill终止,在类似的版本中,sigkill通过在该点关闭管道来工作。您显示的Perl代码不会编译。例如
stop\u stream(){…}
缺少
sub
,并且您使用了一个原型(从来都不是一个好主意)说它需要零参数。并且您没有声明
$streampid
。请显示您的真实代码最新编辑显示了编译版本。