大人になっても苦手な食べ物、ありますか?

system関数を用いて、ループ内で外部プログラムを連続的に実行しています。ところが、時々、無限ループに近い状態に陥ってしまうデータがあるので、時間制限を設けて、その時間内に終了しない場合には、そのプロセス(外部プログラム)を強制終了させたいのです。
また、もし、強制終了させた場合には、それと分かるように戻り値を返してもらえると、なお良いです。

この仕組みを実現する手法、もしくは、モジュール等を教えて頂けないでしょうか。

A 回答 (2件)

自前のsystemであるmysystemを自作します。


これは、第1引数にタイムアウト時間(秒)を取り、
第2引数以降は、systemを呼び出すときのパラメータの集合をとります。
mysystemの戻り値は
-1:fork失敗(通常あり得ない)
-2:タイムアウト(第1引数で指定された時間内にコマンドが終了しなかった)
255:execエラー(第2引数以降が正しくないのでコマンドとして実行できない)(但し、この仕様は255を終了ステータスで返すコマンドがあるとそのステータスと区別ができない、ということがあるが、まず、これが問題になることはないだろうという前提で作成。対策が無いわけではないが、ソースが複雑になるので、とりあえず、簡易版)
とします。
以下ソースです。
------------------------------------------
#! /usr/bin/perl
$stime = time();
$result = &mysystem(60,@ARGV);
$etime = time();
printf ("result=%d,excuted time=%d\n",$result,$etime-$stime);

#自前のsystem
# P1:タイムアウト時間(単位:秒)
# P2:systemへ渡す文字列
# 戻り値: -1:fork error
# 255:exec error(コマンド文字列不正)
# -2:timeout
# 以外:コマンドの終了ステータス
sub mysystem
{
use POSIX qw( SIGKILL );
my $timeout = shift(@_); #タイムアウト時間
my @cmd = @_; #コマンドリスト
my $pid = fork();
# fork失敗
if (!defined($pid)){
return -1;
}
#子プロセスの場合
if ($pid == 0){
exec(@cmd);
# execが成功すれば戻ってこない
# 下記の文が実行されるのはexec失敗の場合だけ
exit(255);
}
#親プロセスの場合
while($timeout>0){
#my $ret = POSIX::waitpid($pid,&POSIX::WNOHANG);
my $ret = waitpid($pid,&POSIX::WNOHANG);
#プロセス終了時(プロセスの終了ステータスは$?に格納されている)
if ($ret != 0){
#プロセスの終了ステータスを返す
printf("ret=%d,pid=%d,sts=%d\n",$ret,$pid,$?);
return ($?/256);
}
# プロセスが終了していない場合1秒待つ
$timeout--;
sleep(1);
}
#タイムアウト検出時
#子プロセスをKILLする
kill(SIGKILL,$pid);
#殺した子プロセスをみとる(成仏させる)
waitpid($pid,0);
# タイムアウトで終了
return -2;
}
------------------------------------------
上記のスクリプトをsampl.plで保存し、
sampl.pl 実行したいコマンド名
と入力して下さい。
その 実行したいコマンド名を実行し、60秒以内に完了しなければ、
そのコマンドをKILLし、-2で戻ります。(linux(cent-os4.4))で動作確認済みです。
    • good
    • 0
この回答へのお礼

希望していたものを遥かに上回る素晴らしいプログラムを書いていただき、ありがとうございます。
使いやすさの点や、戻り値の値など、とても素晴らしいです。
おかげさまで、やりたい処理ができそうです。
ありがとうございました。

お礼日時:2008/07/23 13:11

>この仕組みを実現する手法、もしくは、モジュール等を教えて頂けないでしょうか。


unix系なら、fork,exec,killの組み合わせでなんとかなりそうですが、OSはなんでしょうか?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
OSはLinuxです。
よろしくお願いします。

お礼日時:2008/07/23 10:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報