« 「1日30分」を続けなさい! | トップページ | 無理なく続けられる年収10倍アップ時間投資法 »

2007年10月23日 (火)

インターバルタイマその2

以前に書いたインターバルタイマのソースがあまりにもアレだったので、コメント文も含めて書き直し。書き直しのポイントは

  • シグナルハンドラを極力シンプルに(一行だけ)
  • sigaction()によるシグナルハンドラの設定の処理と、setitimer()によるインターバルタイマの設定の処理と、タイマを待つ処理を分離
  • コメントを分りやすく追加

といったところです。ただ、課題はまだあって

  • 無限ループで負荷が高くなる(sleepでやると低いのはなぜ?)
  • sigaction構造体の各メンバの意味がイマイチ不明

それはともかく、ソースはこんな感じです。

#include <stdio.h>
#include <sys/time.h>
#include <signal.h>
#include <unistd.h>

#define TIMER_ON  (1)
#define TIMER_OFF (0)

/* シグナル発生判定用グローバル変数 */
static int g_timer = TIMER_OFF;

/* プロトタイプ宣言 */
static void handler(int); // シグナルハンドラ

/* main */
int main(int argc, char **argv){
  // シグナル動作規定変数宣言
  struct sigaction s_act;         // シグナル動作規定変数

  /* シグナル動作規定変数設定 */
  s_act.sa_handler = handler;  // シグナルハンドラの設定
  sigemptyset(&s_act.sa_mask); // シグナルハンドラ実行時のマスク
  s_act.sa_flags = 0;          // シグナル受信後の動作

  /* シグナル動作変更 */
  sigaction(SIGALRM, &s_act, NULL);

  /* インターバルタイマ関連変数宣言 */
  struct timeval s_initial_time;  // タイマ初期値時間
  struct timeval s_interval_time; // タイマ間隔時間
  struct itimerval s_itimer;      // タイマ変数
  struct timeval s_now;           // 現在時刻

  /* タイマ初期値・間隔用時間変数設定 */
  s_initial_time.tv_sec   = 3;
  s_initial_time.tv_usec  = 0;
  s_interval_time.tv_sec  = 2;
  s_interval_time.tv_usec = 0;

  /* インターバルタイマ変数設定 */
  s_itimer.it_value    = s_initial_time;  // 初回
  s_itimer.it_interval = s_interval_time; // 間隔

  /* 現在時刻取得と表示 */
  gettimeofday(&s_now, NULL);
  printf( "%ld.%ld sec start!\n", s_now.tv_sec, s_now.tv_usec);

  /* インターバルタイマ開始 */
  setitimer(ITIMER_REAL, &s_itimer, NULL);

  /* シグナル待ち無限ループ */
  while(1){
    if (TIMER_ON == g_timer){  // タイマ期限到来

      /* 現在時刻取得と表示 */
      gettimeofday(&s_now, NULL);
      printf( "%ld.%ld sec\n", s_now.tv_sec, s_now.tv_usec);

      /* フラグ倒す */
      g_timer = TIMER_OFF;
    }
  }
  return 0;
}

/* シグナルハンドラ */
static void handler(int sig){
  g_timer = TIMER_ON;
}

で、コンパイル&起動すると。。。

[lucy@fedora7 interval_timer]$ gcc -Wall -o interval_timer interval_timer.c
[lucy@fedora7 interval_timer]$ ./interval_timer
1193071162.820757 sec start!
1193071165.826145 sec
1193071167.836152 sec
1193071169.846293 sec
1193071171.861893 sec
1193071173.868028 sec
1193071175.878992 sec    ←★Ctrl-Cで停止

[lucy@fedora7 interval_timer]$

こんな感じになります。何もしなくても10msec程度ずれますね。いろいろやるともっとずれます。coLinuxだからかもしれませんが。。。

|

« 「1日30分」を続けなさい! | トップページ | 無理なく続けられる年収10倍アップ時間投資法 »

コメント

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/207693/16845426

この記事へのトラックバック一覧です: インターバルタイマその2:

« 「1日30分」を続けなさい! | トップページ | 無理なく続けられる年収10倍アップ時間投資法 »