加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl – 如何判断管道打开过程是否已终止?

发布时间:2020-12-15 21:46:37 所属栏目:大数据 来源:网络整理
导读:假设使用以下代码创建句柄: use IO::File;my $fh = IO::File-new;my $pid = $fh-open('some_long_running_proc |') or die $!;$fh-autoflush(1);$fh-blocking(0); 然后用这样的循环读取: while (some_condition_here) { my @lines = $fh-getlines; ... sle
假设使用以下代码创建句柄:
use IO::File;

my $fh = IO::File->new;

my $pid = $fh->open('some_long_running_proc |') or die $!;

$fh->autoflush(1);
$fh->blocking(0);

然后用这样的循环读取:

while (some_condition_here) {
    my @lines = $fh->getlines;
    ...
    sleep 1;
}

作为some_condition_here,如果管道另一端的进程终止,那么它将返回false?

$fh-> eof的测试将无法工作,因为该过程仍然可以在不打印任何新行的情况下运行.测试$fh->打开似乎没有做任何有用的事情.

目前我正在使用$pid =! waitpid($pid,WNOHANG)似乎适用于符合POSIX标准的环境.这是最好的方法吗?在Windows上怎么样?

解决方法

在使用select时,
use strict;
use warnings;

use IO::Select qw( );

sub process_msg {
    my ($client,$msg) = @_;
    chomp $msg;
    print "$client->{id} said '$msg'n";
    return 1;  # Return false to close the handle.
}

my $select = IO::Select->new();
my %clients;

for (...) {
    my $fh = ...;
    $clients{fileno($fh)} = {
        id  => '...'
        buf => '',# ...
    };

    $select->add($fh);
}

while (my @ready = $select->can_read) {
    for my $fh (@ready) {
        my $client = $clients{ fileno($fh) };
        our $buf; local *buf = ( $client->{buf} );

        my $rv = sysread($fh,$buf,64*1024,length($buf));
        if (!$rv) {
            if (defined($rv)) {
                print "[$client->{id} ended]n";
            } else {
                print "[Error reading from $client->{id}: $!]n";
            }

            print "[Incomplete message received from $client->{id}]n"
                if length($buf);

            delete $clients{ fileno($fh) };
            $select->remove($fh);
            next;
        }

        while ($buf =~ s/^(.*n)//) {
            if (!process_msg($client,"$1")) {
                print "[Dropping $client->{id}]n";
                delete $clients{ fileno($fh) };
                $select->remove($fh);
                last;
            }
        }
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读