2008-04-06から1日間の記事一覧

16.22 シグナルを致命的エラーに変換する

捕捉するように設定していないシグナルが原因となってプログラムが強制終了させられる場合、通常はENDブロックが実行されない。 sigtrapプラグマを使用する use sigtrap qw(die untrapped normal-signals);

16.21 動作のタイムアウト

動作が一定の長さの時間を超えて実行され続けることのないようにしたい。 SIGALARMハンドラを設定して、dieを呼び出す。 eval { local $SIG{ALARM} = sub { die "alarm clock restart" }; alarm 10; # アラームを10秒に設定する eval { # 実行するのに時間の…

16.20 シグナルをブロックする

シグナルの受け取りを遅らせたい。その目的は、任意の時点でプログラムに割り込む可能性のあるシグナルによって、予想外の動作が引き起こされるのを防止するためである。 sigprocmaskシステムコールに対するPOSIXモジュールのインターフェースを使用する。 u…

16.19 ゾンビプロセスの蓄積を防ぐ

終了した子プロセスの状態を確認する必要がない場合 $SIG{CHLD} = 'IGNORE'; 終了したプロセスの状態を意図的に確認する必要がある場合 use POSIX ":sys_wait_h"; $SIG{CHLD} = \&REAPER; sub REAPER { my $stiff; while (($stiff = waitpid(-1, WNOHANG)) >…

16.17 シグナルハンドラを書く

16.18 Ctrl+Cを捕捉する

SIGINTに対応するハンドラを設定する。 $SIG{INT} = 'IGNORE'; 何らかの処理を行う場合 $SIG{INT} = \&tsktsk; sub tsktsk { $SIG{INT} = \&tsktsk; warn "\aThe long habit of living indisposeth us for dying.\n"; }

16.16 シグナルハンドラを一時的に上書きする

localを使用して、シグナルの動作を一時的にオーバーライドする # シグナルハンドラ sub ding { $SIG{INT} = \&ding; warn "\aEnter your name!\n"; } # 名前の要求をするために、SIGINTをオーバーライドする。 sub get_name { local $SIG{INT} = \&ding; my…

16.15 シグナルハンドラを設定する

%SIGハッシュを使用して、独自のハンドラをインストールする。 $SIG{QUIT} = \&got_sig_quit; # SIGQUITを受け取るたびに&got_sig_quitを呼び出す $SIG{PIPE} = 'got_sig_pipe'; # SIGPIPEを受け取るたびにmain::got_sig_pipeを呼び出す $SIG{INT} = sub {$o…

16.14 シグナルを送信する

killコマンドを使用する kill 9 => $pid; # $pidにシグナル9を送信する kill -1 => $pgrp; # ジョブ全体にシグナル1を送信する kill USR1 => $$; # 現在のプロセスにSIGUSR1を送信する kill HUP => @pids; # @pidsに含まれるプロセスにSIGHUPを送信する

16.13 利用可能なシグナルの一覧を表示する

% kill -l % perl -e 'print join(" ", keys %SIG), "\n";

16.12 異なるプロセス間で変数を共有する

forkによって分離したプロセスの間や関連性のないプロセスの間で変数を共有したい。 使用しているOSにおいて、SysV IPCがサポートされている場合には、それを使用する。

16.11 名前付きパイプを使用して、プロセスをファイルのように見せる

ファイルに対するアクセスを全てプログラムによって捕捉したい。例えば、自分の~/.planファイルをランダムな引用を返すプログラムにする。 名前付きパイプを使用する。 シェルで名前付きパイプを作成する。 % mkfifo /path/to/named.pipe 読み取り側のコード…

16.10 関連プロセスの間で通信する

関連性のある2つのプロセスがあり、これらの間で通信を行う必要がある。ただし、open, system, およびバッククォートによって行える以上に厳密な制御を行いたい。 pipeを使用してから、forkを使用する my ($reader, $writer); pipe $reader, $writer; if (fo…

16.9 別のプログラムの入力、出力、およびエラーを制御する

コマンドの入力、出力、およびエラーの各ストリームを完全に制御したい。 細心の注意を払いながら、標準モジュールのOPC::Open3を使用する。

16.8 別のプログラムの入力と出力を制御する

別のプログラムに対して、書き込みと読み取りを同時に行いたい。 標準モジュールのIPC::Open2を使用する use IPC::Open2; $pid = open2(*README, *WRITEME, $program); print WRITEME "here's your input\n; close(WRITEME); $output = <README>; close(README); wai</readme>…

16.7 プログラムのSTDERRを読み取る

コマンドのSTDOUTとSTDERRをまとめて変数に代入する。 $output = `cmd 2>&1`; # バッククォートの場合 # または、 $pid = open(PH, "cmd 2>&1 |"); # パイプ付きのopenの場合 while (<PH>) { } # さらに読み取りを行う コマンドのSTDOUTを変数に代入し、STDERRを</ph>…

16.6 入力を前処理する

gzipやcompressによって圧縮されたファイルをgzipによって圧縮解除して、自動的に処理する。 @ARGV = map { /\.(gz|Z)$/ ? "gzip -dc $_ |" : $_ } @ARGV; while (<>) { # ... } ファイルを処理する前にURLを取得する @ARGV = map { m#^\w+://# ? "GET $_|" …

16.5 出力をフィルタ処理する

自分のプログラムの出力を後処理する必要があるが、そのための独立したプログラムを作成したくない。 暗黙的にforkが行われる形式でopenを使用して、自分のプログラムにフィルタを接続する。 head(100); while (<>) { print; } sub head { my $lines = shift…