2

我已经使用 IO::Pipe 设置了另一个我观察输出的进程

my $pipe  = IO::Pipe->new();
my $fh    = $pipe->reader( $dirWatcher );

然后我设置了一个 IO::Select 来观看 $fh。

一切正常,但有时我想终止 $dirWatcher 进程。

我的第一个想法是在创建阅读器时保存 PID,然后在需要时调用 kill。

但是, IO::Pipe 似乎没有为我提供了解 PID 的方法。

那么我是否必须复制 IO::Pipe::reader 的功能?有没有我想念的简单方法?

4

2 回答 2

1

IO::Pipe的readerandwriter方法返回 IO::Pipe::End 的实例。此类使用close方法专门化 IO::Handle。

sub close {
    my $fh = shift;
    my $r = $fh->SUPER::close(@_);

    waitpid(${*$fh}{'io_pipe_pid'},0)
        if(defined ${*$fh}{'io_pipe_pid'});

    $r;
}

进程 ID 存在但未在公共接口中公开。这似乎是一个差距。

您可以在以下程序中获取 pid。

#! /usr/bin/env perl

use strict;
use warnings;

use IO::Pipe;

my $pipe = IO::Pipe->new;
my $fh = $pipe->reader("sleep 5; echo hi");

my $pid = ${*$pipe}{'io_pipe_pid'};
system "ps", "ww", $pid;

print while <$fh>;

输出:

$ ./get-reader-pid
  PID TTY 状态时间命令
 3500 点/0 S+ 0:00 sh -c 睡眠 5;回声嗨
[5 秒等待]
你好

正如perlmodlib文档所指出的,深入对象的内部并不是什么严重的罪行。然而,了解风险。

Perl 不会像您在其他语言(如 C++、Ada 或 Modula-17)中习惯的那样强制执行其模块的私有和公共部分。Perl 并不热衷于强制隐私。它宁愿你呆在它的客厅外面,因为你没有被邀请,而不是因为它有猎枪。

你可能会觉得这样做有点肮脏,你应该这样做。它不是公共接口的一部分,因此如有更改,恕不另行通知。实际上,发生变化的可能性很低,即使发生变化,您也可以轻松适应。

于 2012-05-28T12:36:10.993 回答
0

来自perldoc IO::Pipe

           use IO::Pipe;

           $pipe = new IO::Pipe;

           if($pid = fork()) { # Parent
               $pipe->reader();

               while(<$pipe>) {
                   ...
               }

           }
           elsif(defined $pid) { # Child
               $pipe->writer();

               print $pipe ...
           }
于 2012-05-28T05:12:25.780 回答