perlメモ:alarmを使ったタイムアウト処理はてなブックマーク数

| コメント(0) | トラックバック(0)

perlでalarmを使ってタイムアウト処理を行う方法。割り込みとか、アラームとか、タイマーとかタイムアウト処理とか言ったりします。

perlでWebをGETするプログラムを書いたりすると、相手のサーバーが死んでいると、応答が無くなってプログラムが止まったままにになったりします。WebのGETにかかわらず、通信関係ではよくあることですが、例えば複数のURLを定期的にチェックするプログラムをperlで書いたときにチェックしてるURLのうちの一つでもサーバーが落ちたりしてると応答が帰ってこなくて他のURLまでチェックできなくなってしまったりします。これでは困るので、タイムアウト処理が必要になるのですがその場合に重宝するのがalarmです。


perl.comのサンプルソースをチョットいじったサンプルです。

下記のサンプルだと実行後while(1)の所で無限ループに陥ってしまいますが、その前で
alarm 10でalarmの設定を行っているので10秒後アラームシグナルによる割り込みが発生し
evalで囲まれた範囲の処理を抜けます。

$SIG{ALRM}の行は、割り込みでevalを抜けた際に$@に格納される文字を指定しています。
実際eval{};を抜けたあと$@の内容を表示するとしたのサンプルでは「alarm」が格納されているのが確認できます。

eval{};を抜ける直前のalarm 0;はalarmの解除です。問題なくeval{};で囲まれた範囲を終わるので最後にアラームによる割り込みを解除しています。

追加でeval{};を抜けた直後にもalarm 0;を書いている場合があるソースを見かけますが、alarm以外の原因で抜けた場合などの為に念の為に書いているのだと思います。

eval{};を抜けたあとは、 $@の中身があるかチェックして、正常にeval{};を抜けたのかチェックします。$@の中身があれば、何らかの割り込みでeval{};を抜けているので$@の中身をチェックしてeval{};を抜けてきた原因をチェックします。下記の例では$@の中身が「alarm」かどうかチェックしてalarm以外で抜けてきている場合は、dieでプログラムを終了しています。

eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
alarm 10;
my $cnt=0;
while(1){
print "テストループ:",++$cnt,"\n";
sleep(1);
}
alarm 0;
};

if ($@) {
die unless $@ eq "alarm\n"; # propagate unexpected errors
print "time out [$@]\n";
# timed out
}else{
print "didn't\n";
# didn't
}

通信処理などに上記を応用する場合は、送受信処理の部分をeval{};でくくって、eval{};のはじめの方でタイムアウト秒数を指定、eval{};を抜ける直前でalarm 0;によりタイマーをクリアするという流れでいいかと思います。

実際perl.comのサンプルもソケットをsysreadしているサンプルですので詳しくはそっちを見てください。


▼perl.com alarm
http://www.perl.com/doc/manual/html/pod/perlfunc/alarm.html

トラックバック(0)

ここだよ

トラックバックスパム対策の為この記事にトラックバックを行うにはトラックバック元の記事中にこのページのURL「http://blog.kumacchi.com/2007/09/perlalarm.html」を含めてください。

コメントする

RSS

rss

ウェブページ

よく読まれている記事

アクセスランキング

 

QRコード

KUMA TYPE QRコード

マイページ

yays

このブログ記事について

このページは、くまっちが2007年9月15日 17:49に書いたブログ記事です。

ひとつ前のブログ記事は「[コンチェルトゲート]さっき気付いたんだけど」です。

次のブログ記事は「Sygateパーソナルファイアウォール5.6でファイル共有が出来ない場合」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

  • seo
track feed KUMA TYPE フィードメーター - KUMA TYPE あわせて読みたい