sleep

指定の秒数だけブロックする

構文

解説

sleepEXPR に指定した整数の秒数だけスクリプトをスリープします。 もし EXPR に何も指定しなければ永久にスリープします。 この関数は実際にスリープした秒数を整数で返します。

EXPR は正の整数でなければいけません。 もし EXPR に小数を指定すると、エラーにはなりませんが、小数点以下の部分は無視されます。 もし負の整数を指定すると、スリープせずに、警告を発し、エラーを $! にセットし、0 を返します。

my $sec1 = sleep 3;    # 3 秒スリープする
print $sec1, "\n";     # 3

my $sec2 = sleep 3.5;  # 小数点以下は無視され 3 秒スリープする
print $sec2, "\n";     # 3

my $sec3 = sleep -1;   # マイナスの値を指定するとスリープしない
print $sec3, "\n";     # 0

sleep;   # 何も指定しないと永久にスリープする

もし EXPR に 0 を指定すると、エラーにはならず、 一瞬だけスリープしますが、実際にどれほどスリープするのかは OS に依存します。

my $sec = sleep 0;    # 一瞬スリープする
print $sec, "\n";     # 0

sleep は、該当プロセスが SIGALARM のようなシグナルを受け取ると中断することができます。 実際には次のように evaldie を組み合わせて、中断を受け付けられるようにします。

alarm 5; # 5 秒後に ARLM シグナルを発出

eval {
    # ARLM シグナルを受信したら die で eval を抜けるよう、
    # 無名サブルーチンをセット
    local $SIG{ALRM} = sub { die "ARLM\n" };

    # 永久スリープを開始
    sleep;
};

if ( $@ eq "ARLM\n" ) {
    print "ARLM シグナルを受信しました。\n";
}
else {
    print "別の理由で処理が失敗しました: $@\n";
}

もし 1 秒未満の正確なスリープを必要とするなら、 Time::HiRes モジュールの usleep を使うと良いでしょう。 usleep ならマイクロ秒の単位でスリープ時間を指定することができます。 Time::HiRes は Perl 5.8 から標準モジュールになっています。

use Time::HiRes qw(usleep);
usleep(2450000);    # 2.45 秒 (2,450,000 マイクロ秒) スリープする

select 関数を使うこともできます。 最初の 3 つの引数に undef を指定し、 第 4 引数にスリープ秒数を小数点付きで指定します。

select undef, undef, undef, 2.45;    # 2.45 秒だけスリープ