POSIX Timer

  • timer_createを使ってPOSIX タイマーを作成する。
  • timer_createの1つめの引数でタイマーの種類を指定する。 CLOCK_REALTIMEを指定した場合は、タイマーの種類として実時間を指定する。
  • timer_createの2つめの引数でタイマーが満了したときにプロセスに対して発行するシグナルを指定できる。 NULLを指定した場合はデフォルトの動作となり、タイマーが満了するとSIGALRMが発行される。 
  • timer_createの3つめの引数で作成したタイマーのIDを取得する。
  • 作成したタイマーを開始するには、timer_settimeを使ってタイマーが満了するまでの間隔を指定する。
  • timer_settimeでは、タイマーが開始されてから最初に満了するまでの時間(itimerspec.it_value)と、その後満了するまでの間隔(itimerspec.it_interval)を指定することが出来る。
  • itimerspec.it_intervalに0を指定した場合は、itimerspec.it_valueで指定した時間に満了した後はシグナルを発行しなくなる(一度だけシグナルを発行するタイマーとなる)。
  • timer_settimeの2つめの引数にTIMER_ABSTIMEを指定すると、3つめの引数で指定した時間は現在からの相対時間ではなく、システムのクロックに基づく絶対時間と解釈される。
  • タイマーが不要になったら、timer_deleteで作成したタイマーを削除する。

使用例

// gcc -lrt

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

//
// シグナルハンドラ
//
void handler( int signo )
{
  // printfは非同期シグナルセーフな関数ではないため、
  // 本当ならシグナルハンドラで使用すべきではない
  printf( "!signal %d received\n", signo );
}


int main( void )
{
  timer_t timer_id;
  struct sigaction sigact;
  struct itimerspec itval;

  // シグナルハンドラを設定する
  sigact.sa_handler = handler;

  // シグナルハンドラの動作を変更する為のフラグ(特に指定しない)
  sigact.sa_flags = 0;

  // シグナル集合を空にする
  // (シグナルハンドラを設定する対象のシグナルをクリアする)
  sigemptyset( &sigact.sa_mask );

  // SIGALRMに対してシグナルハンドラを設定
  sigaction( SIGALRM, &sigact, NULL );

  // タイマーを作成
  timer_create( CLOCK_REALTIME, NULL, &timer_id );

  // タイマーが満了するまでの時間
  // (タイマーを設定してから3秒後に満了し、その後0.25秒おきに
  // 満了させる)
  itval.it_value.tv_sec = 3;
  itval.it_value.tv_nsec = 0;

  itval.it_interval.tv_sec = 0;
  itval.it_interval.tv_nsec = 250 * 1000 * 1000;

  // タイマーを設定
  timer_settime( timer_id, 0, &itval, NULL );

  int count;

  for ( count = 0; count < 10; count++ )
  {
    // シグナルの受信を待機する
    pause();

    printf( "count: %d\n", count );
  }

  // タイマーを削除
  timer_delete( timer_id );
}