!!! 経過時間を計るプログラム [[GLib::チュートリアル]]の中にある,イベントループを用いた方が簡単かもしれません. !! プログラム例 * http://svn.cis.iwate-u.ac.jp/svn/csd/Examples/misc/timer !! 解説 ゲームのプログラムなどで,時間の経過によって処理を行う場合があります. この例では,1秒毎にある変数の値を1ずつ増やし,その値(経過 秒)を表示するプログラムです. プログラム中で, 8< while(1) { sleep(10); if (newClock>Clock) { Clock = newClock; printf("Clock(%d) uClock(%d)\n", Clock, uClock); } >8 という個所がありますが, while の中では, * sleep(10): 10秒間プログラムがスリープ(停止状態) * newClock 変数と Clock変数の値が異なると,Clock を更新し,その値を表示 を繰り返しています.しかし,このループ中 newClock 変数の値を変更している個所はありません. NewClock の値を変更しているのは, * TimerHnadler 関数の中ですが,この関数を呼び出しているところはありません. * これは Unix のシグナルという機構を使って実現されています. シグナルは,プログラム(厳密にはプロセス)に対する割り込みを伝える機構です. プロセスが * シグナルを処理する関数を登録しておくことで, * シグナルを受け取った時に処理関数が実行されます. この処理は, * プログラムの実行を一時中断し, * シグナルに対する処理が行われ, * その処理後は,中断された個所から再開されます. まず,1秒毎の目覚まし時計の設定方法ですが, 8< struct itimerval mytimer; (mytimer.it_interval).tv_sec = 1; (mytimer.it_interval).tv_usec = 0; (mytimer.it_value).tv_sec = 1; (mytimer.it_value).tv_usec = 0; >8 itimervalは時間を設定するための構造体です.ここでは1秒後に鳴る目覚まし時計を指定しています. 目覚まし時計を仕掛けるのが 8< setitimer(ITIMER_REAL, &mytimer, NULL); >8 そのSIGARLMが起こった時に呼び出される関数が TimerHandler ですが,それを 8< signal(SIGALRM, TimerHandler); >8 で指定しているわけです. TimerHandler関数が行うことは, 8< void TimerHandler() { newClock = Clock+1; signal(SIGALRM, TimerHandler); } >8 NewClockの値に1を足して,再度,シグナル SIGARLM 処理関数を指定しています.