« FizzBuzz | トップページ | coLinuxその1 »

2007年5月18日 (金)

インターバルタイマ

そもそもCでシグナルとか扱った経験が無いのを常々反省しておりまして、ためしにインターバルタイマなど調べて使ってみました。以下やっとこさ書いたダメソース。

setitimer()システムコールを使って2秒(実時間)のインターバルタイマを開始。2秒おきにSIGALRMを受信すると、現在時刻(timeval構造体)を取得して、その「マイクロ秒部分」を表示する。

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

/* シグナルハンドラ */
void handler(int sig){
  struct timeval tv;

  /* 現在時刻取得 */
  gettimeofday(&tv, NULL);

  /* マイクロ秒部分を表示 */
  printf( "%ld usec\n", tv.tv_usec);
}

/* main */
int main(int argc, char **argv){
  struct itimerval itimer;
  struct timeval interval;
  struct sigaction m_act;

  /* 時間間隔設定 */
  interval.tv_sec = 2;
  interval.tv_usec = 0;

  /* インターバルタイマ変数設定 */
  itimer.it_interval = interval;
  itimer.it_value = interval;

  /* sigaction構造体設定。シグナルハンドラの設定等 */
  m_act.sa_handler = handler;
  sigemptyset(&m_act.sa_mask);
  m_act.sa_flags = 0;

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

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

  /* 空回り無限ループ */
  while(1){
 
  } 
  exit(0);
}

 空回り無限ループは何とかならんかと思ったのですが。最初sleepとかしてたんだけど、それだとSIGALRMがかぶってプロセス終了しちゃうし。(なんでだろ?理由を考えよ>ワシ)

 あと、シグナルハンドラの中ってちょっと危険地帯なので、printfとか使っちゃダメらしい。理由はなんとなくしか分かんないんだけど(ってことは分かってない)。それに関連してるのかも知れんけど、上記プログラムを二つのウィンドウで二つ並行して実行したら、出力が2秒ごとにならなくなった。互いに干渉しているっぽい。なんでだろ?gettimeofdayやprintfがまずい?Linuxのシグナル処理のバグ?どうやらウィンドウを切り替える時にタイミングがずれる。負荷がかかるせいかな?

|

« FizzBuzz | トップページ | coLinuxその1 »

コメント

コメントを書く



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




トラックバック

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

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

« FizzBuzz | トップページ | coLinuxその1 »