Perl:一定時間でループ処理から脱出するプログラム

 レンタルサーバーだと1回のCGIの実行時間が制限されているので、長いループ処理の途中で制限時間が来たら処理を中断するプログラムを考えてみました。

    #!/usr/local/bin/perl
    my $t=time;   #起動時間
    my $r;        #経過状況保持用
    my $i;        #ループ用
    my $start=0;  #スタート位置(★1)
    my $end=15;   #ループ回数
    my $limit=5;  #ループ滞在時間(★2)

    #ループ
    for($i=$start;$i<=$end;$i++){
        $r.="$i ok\n";  #何らかの処理(★3)
        sleep(1);
        if($limit < time-$t){$i++;last;} #時間でループ離脱(★4-1 or 2)
    }

    #処理後の表示(★5)
    if ($i<=$end){
        #処理が途中ならNext表示
        $r.="Next $i \n";
        $i--;
        $r.="($start - $i ok)\n";
    }else{
        #処理が完了してれば完了表示
        $i--;
        $r.="0 - $i All ok \n";
        $r.="($start - $i ok)\n";
    }

    #書き出し
    print "Content-type: text/plain\n\n$r";
    exit;

(★1)
初回は「0」、2回目以降はプログラム終了時に表示されるNextの値を入れる
(本来は2回目以降はフォームやファイルから読み込むものですが手動で書き直してください)

(★2)
ループ滞在時間は秒単位で指定します(5なら5秒)
プログラムの起動から終了までの時間では無いので、レンタルサーバーの制限時間ギリギリに設定するのはダメです。
詳しくは、次の3点が含まれていないので注意。
 a.$t=timeを読み込むまでの時間
 b.1回分の★3の処理時間(★3の処理後に終了判定し次のループに入るため)
 d.終了判定後の終了処理をする時間
・例 1回の起動0.5秒・1回のループ処理に1.2秒かかったとすると
 「起動0.5→処理1→判定1.7秒→処理2→判定3.9秒→処理3→判定5.1秒・・・」
 0.1秒を指定した場合は「1.7秒+終了処理」かかります。
 4秒を指定した場合は、処理2の判定で3.9秒なのでもう1ループするため「5.1秒+終了処理」かかります。

(★3)
ここに処理させたいプログラムを書きます。
最低1回は読み込みます。したがって上記2-bや例にあるように、この処理1ループだけでレンタルサーバーの制限にギリギリの場合は実行できない。

(★4-1)
処理の後に離脱処理があるので、滞在時間を0に設定しても最低1回は★2の処理が行われます。

(★4-2)
$i++;としてるのは、ループ正常終了時と結果をそろえるため。
上記の例だと
forが最後まで回ると、$i=15の処理が終わり→$endより大きくなる$i=16で終了します。
forが$i=15の時滞在時間となった場合、$i++;が無いと
$i=15の処理が終わり→ループ離脱だと$i=15のままとなり、$i=15の処理が終わっているのに
結果が変わってしまうため $i++;を加えています。

(★5)
どこまでループしたか知りたい時は ★3-2で$i++;を戻す必要がある


実際の利用では、ループ途中で抜けた場合には変数などを書き出す処理や起動時にそれらを読み出す処理が必要です。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA