sleep
一定時間だけプログラムの実行を止める方法のその 1 として,
sleep
(3) を使います. なお, sleep
(1)
というコマンドもあるので, マニュアルを見るときは
man 3 sleep とします. 使い方は簡単で,
引数に止まる秒数 (もちろん整数, 正確には unsigned int) を与えてやれば,
その間プログラムは止まってくれます.
プログラムが止まっているときは, CPU も止まるのか? 答えはノー. プログラムの実行が止まっている間, CPU は平然と別の仕事をしています. マルチタスクなんで, 当たり前といえば当たり前ですね.
本当に, sleep
は指定した時間だけ眠ってくれるのか?
それを調べるためには, sleep
の前後で時間を計測してやる必要があります. 時間を計ってくれる関数には,
time
(2) があります. こいつは,
グリニッジ標準時で 1970 年 1 月 1 日 0 時 から流れ去った時間を,
秒単位で返してくれます. グリニッジ標準時でということは,
コンピュータの世界では日本は 1970 年 1 月 1 日 9 時から始まってるんですね.
time
の使い方も簡単で, time_t
な変数
t
に対して, t = time()
とか
time(&t)
とかすれば OK (のはず) です.
でもここでは, gettimeofday
(2) を使います.
理由は, gettimeofday
だと,
1970 年 1 月 1 日 0 時からの経過時間をマイクロ秒 (0.000001 秒!)
単位で教えてくれるから. 使い方は, struct timeval
な変数 tv
と, struct timezone
な変数 tz
に対して,
gettimeofday(&tv, &tz)
とやれば OK.
tv.tv_sec
に秒の部分が,
tv.tv_usec
にマイクロ秒の部分が入ってます.
なお tv.tv_usec
は, 7 桁以上にはならないでしょう.
tz
は, 今回は面倒なので省略.
というわけで, 実験したプログラム. SLEEP_SEC
秒だけ
sleep
で休み,
その後に gettimeofday
で時刻を調べるという作業を,
LOOP
回だけ実行します. 時刻は
tv[LOOP]
という配列に格納し,
全てが終わってから出力します.
21 行目. 本来なら
gettimeofday(&(tv[i]), &tz)
とするのが筋でしょうが,
より速くを目指したいので, tv
のほうは直接ポインタを指定するようにしています.
これで, どれだけ速いのかはわかりませんが.
1 /* 2 * test_sleep.c 3 * sleep を使って, 間隔をあけるテスト 4 */ 5 6 #include <stdio.h> 7 #include <unistd.h> 8 #include <sys/time.h> 9 10 #define SLEEP_SEC 10 11 #define LOOP 5 12 13 int main() 14 { 15 int i; 16 struct timeval tv[LOOP]; 17 struct timezone tz; 18 19 for(i=0; i<LOOP; i++){ 20 sleep(SLEEP_SEC); 21 gettimeofday(tv + i, &tz); 22 } 23 24 for(i=0; i<LOOP; i++){ 25 printf("%3d : %ld:%06ld\n", i, tv[i].tv_sec, tv[i].tv_usec); 26 } 27 28 return 0; 29 }
普通 (?) の実行結果. 良く見るとわかりますが, 1 ミリ秒程度の誤差があるけれど, 10 秒という時間を計測しているということを考えればすごいことですね.
0 : 890298243:849071 1 : 890298253:848975 2 : 890298263:848975 3 : 890298273:848976 4 : 890298283:848976
次の例はいじわるして, プログラムの実行中に kterm
を立ち上げたり du
したりしたときのものです
(う〜む, 私一人で 100M も使っていたのか…).
3 〜 4 ミリ秒の単位で狂ってきますね. マルチタスクな OS の宿命か.
ま, 1% の誤差なら許してくれるでしょう.
0 : 890299088:609103 1 : 890299098:611411 2 : 890299108:611900 3 : 890299118:608997 4 : 890299128:609005
Copyright (C) 1998, Masahiro SATO