ソフトウェア設計及び演習2013
時間の計測
GLib::チュートリアルの中にある,イベントループを用いた方が簡単かもしれません.
以下は過去の事例.
経過時間を計るプログラム
解説
ゲームのプログラムなどで,時間の経過によって処理を行う場合があります. この例では,1秒毎にある変数の値を1ずつ増やし,その値(経過 秒)を表示するプログラムです.
プログラム中で,
while(1) { sleep(10); if (newClock>Clock) { Clock = newClock; printf("Clock(%d) uClock(%d)\n", Clock, uClock); }
という個所がありますが, while の中では,
- sleep(10): 10秒間プログラムがスリープ(停止状態)
- newClock 変数と Clock変数の値が異なると,Clock を更新し,その値を表示
を繰り返しています.しかし,このループ中 newClock 変数の値を変更している個所はありません.
NewClock の値を変更しているのは,
- TimerHnadler 関数の中ですが,この関数を呼び出しているところはありません.
- これは Unix のシグナルという機構を使って実現されています.
シグナルは,プログラム(厳密にはプロセス)に対する割り込みを伝える機構です.
プロセスが
- シグナルを処理する関数を登録しておくことで,
- シグナルを受け取った時に処理関数が実行されます.
この処理は,
- プログラムの実行を一時中断し,
- シグナルに対する処理が行われ,
- その処理後は,中断された個所から再開されます.
まず,1秒毎の目覚まし時計の設定方法ですが,
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;
itimervalは時間を設定するための構造体です.ここでは1秒後に鳴る目覚まし時計を指定しています.
目覚まし時計を仕掛けるのが
setitimer(ITIMER_REAL, &mytimer, NULL);
そのSIGARLMが起こった時に呼び出される関数が TimerHandler ですが,それを
signal(SIGALRM, TimerHandler);
で指定しているわけです.
TimerHandler関数が行うことは,
void TimerHandler() { newClock = Clock+1; signal(SIGALRM, TimerHandler); }
NewClockの値に1を足して,再度,シグナル SIGARLM 処理関数を指定しています.
最終更新日:2013/10/23 16:15:27