シグナルについて調べてたら、定周期でイベント通知するAPI見つけたのでメモ。
今までC言語で定周期処理を実装するのに、処理終わった後でsleepするようなプログラム組んでたけど、こっちの方が楽そう。
以下、試したサンプル。
シグナルハンドラは嫌いなので、シグナルをブロックして、sigwaitでシグナルを待ち受けるようにしてる。
#include <stdio.h> #include <string.h> #include <unistd.h> #include <time.h> #include <sys/time.h> #include <signal.h> #include <pthread.h> #include <errno.h> int main() { // setitimerにより通知されるシグナルをマスク sigset_t sigset; sigemptyset(&sigset); sigaddset(&sigset, SIGALRM); pthread_sigmask(SIG_BLOCK, &sigset, NULL); // タイマ設定 5秒毎に通知 const struct timeval interval = { 5, 0 }; const struct itimerval itimer = {interval, interval}; int ret = setitimer(ITIMER_REAL, &itimer, NULL); if ( ret != 0 ) { perror("setitimer error"); return -1; } int i; for ( i=0; i<10; i++ ) { int signo; sigwait(&sigset, &signo); struct timeval tv; gettimeofday(&tv, NULL); char timebuf[26]; ctime_r(&tv.tv_sec, timebuf); *strchr(timebuf, '\n') = '\0'; printf("[%s] [%06d] signal[%d] recieved.\n", timebuf, tv.tv_usec, signo); // たまに時間かかる処理がある想定 if ( i % 4 == 3 ) { unsigned int waittime = 7; printf("wait %d seconds.\n", waittime); sleep(waittime); } } return 0; }
実行結果
[~]$ cc timer.c -lpthread [~]$ ./a.out [Wed Apr 3 16:15:59 2013] [896773] signal[14] recieved. [Wed Apr 3 16:16:04 2013] [896998] signal[14] recieved. [Wed Apr 3 16:16:09 2013] [896241] signal[14] recieved. [Wed Apr 3 16:16:14 2013] [896484] signal[14] recieved. wait 7 seconds. [Wed Apr 3 16:16:21 2013] [896823] signal[14] recieved. [Wed Apr 3 16:16:24 2013] [896970] signal[14] recieved. [Wed Apr 3 16:16:29 2013] [897215] signal[14] recieved. [Wed Apr 3 16:16:34 2013] [896484] signal[14] recieved. wait 7 seconds. [Wed Apr 3 16:16:41 2013] [896852] signal[14] recieved. [Wed Apr 3 16:16:44 2013] [896946] signal[14] recieved.
(追記)
いいもの見つけたと思ったら、setitimerは廃止予定らしい。*1
代わりにtimer_settime(2)を使えと。
後で調べてみよう。