2

IO::Pipe を使用して、出力を監視する別のプロセスをセットアップしました

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

次に、$fh を監視するように IO::Select をセットアップします。

すべて正常に動作しますが、$dirWatcher プロセスを強制終了したい場合があります。

私が最初に考えたのは、リーダーを作成するときに PID を保存し、必要なときに kill を呼び出すことでした。

しかし、IO::Pipe は PID を知る方法を提供していないようです。

IO::Pipe::reader の機能を複製する必要がありますか? 私が見逃している簡単な方法はありますか?

4

2 に答える 2

1

IO::Pipeのreaderおよびwriterメソッドは、IO::Pipe::End のインスタンスを返します。このクラスは IO::Handle をcloseメソッドで特殊化します。

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 STAT TIME コマンド
 3500pts/0 S+ 0:00 sh -c sleep 5; エコーハイ
【5秒待ち】
こんにちは

perlmodlibのドキュメントが示すように、オブジェクトの内部を突っ込むことは重大な罪ではありません。ただし、リスクを理解してください。

Perl は、C++、Ada、Modula-17 などの他の言語で慣れているように、モジュールのプライベート部分とパブリック部分を強制しません。Perl は強制されたプライバシーに夢中になりません。散弾銃を持っているからではなく、招待されていないので、リビングルームから離れたほうがいいでしょう。

これを行うのは少し汚いと感じるかもしれませんが、そうすべきです。これは公開インターフェースの一部ではないため、予告なく変更される場合があります。実際には、変化の可能性は低く、変化したとしても簡単に適応できます。

于 2012-05-28T12:36:10.993 に答える
0

perldoc IO::パイプから

           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 に答える