Linuxでのタイマー:alarm()とsetimer()
Linuxの下のタイマーは2種類ありますが、以下ではそれぞれ紹介します.
1、alarm
正確さを求めなければalarm()とsignal()で十分です
unsigned int alarm(unsigned int seconds)
関数の説明:alarm()は、パラメータsecondsで指定された秒数後に現在のプロセスに信号SIGALRMを送信するように設定します.パラメータsecondsが0の場合、前に設定した目覚まし時計はキャンセルされ、残りの時間が返されます.
≪戻る値|Return Value|emdw≫:前の目覚まし時計の残りの秒数を返し、前に目覚まし時計が設定されていない場合は0を返します.
alarm()が実行されると、プロセスは実行され続け、seconds秒後にSIGALRMの信号が受信され、その後の(alarm以降の)実行プロセスでその処理関数が実行されます.
#include
#include
#include
#include
#include
#include
void sigalrm_fn(int sig)
{
printf("alarm!/n");
alarm(2);
return;
}
int main(void)
{
signal(SIGALRM, sigalrm_fn);
alarm(1);
while(1) pause();
}
2、setitimer()
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
setitimer()はalarmよりも強力で、3種類のタイマーをサポートしています.
ITIMER_REAL:システムの実際の時間で計算し、SIGALRM信号を送る.
ITIMER_VIRTUAL:-SIGVTALRM信号を送信するプロセスがユーザ状態で費やした時間で計算される.
ITIMER_PROF:SIGPROF信号を送信するプロセスがユーザ状態とカーネル状態でかかる時間で計算される.
setitimer()最初のパラメータwhichはタイマタイプ(上の3つのいずれか)を指定します.2番目のパラメータは、構造itimervalの例です.3番目のパラメータは処理しなくてもいいです.
setitimer()呼び出しは正常に0を返し、そうでなければ-1を返します.
次に、setitimer呼び出しに関する簡単な例を示す.この例では、SIGALRMが1秒おきに発行され、0.5秒おきにSIGVTALRM信号が発行される.
#include
#include
#include
#include
#include
#include
int sec;
void sigroutine(int signo){
switch (signo){
case SIGALRM:
printf("Catch a signal -- SIGALRM /n");
signal(SIGALRM, sigroutine);
break;
case SIGVTALRM:
printf("Catch a signal -- SIGVTALRM /n");
signal(SIGVTALRM, sigroutine);
break;
}
return;
}
int main()
{
struct itimerval value, ovalue, value2; //(1)
sec = 5;
printf("process id is %d/n", getpid());
signal(SIGALRM, sigroutine);
signal(SIGVTALRM, sigroutine);
value.it_value.tv_sec = 1;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 1;
value.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &value, &ovalue); //(2)
value2.it_value.tv_sec = 0;
value2.it_value.tv_usec = 500000;
value2.it_interval.tv_sec = 0;
value2.it_interval.tv_usec = 500000;
setitimer(ITIMER_VIRTUAL, &value2, &ovalue);
for(;;)
;
}
(1) struct itimerval
struct itimerval {
struct timeval it_interval; /* timer interval */
struct timeval it_value; /* current value */
};
itimerval: i --> interval
val --> value
itimerval構造のit_valueは減少する時間であり、この値が0のときに対応する信号を発する.そしてit_valueをit_に設定interval値
(2) setitimer()
setimer()は、itimervalの場合、そのプロセスにタイマを設定する.it_intervalが0でない(it_intervalの両方のドメインが0でない)場合、タイマは有効になります(一定時間ごとに信号が送信されます).
注意:Linux信号メカニズムは基本的にUnixシステムから継承されています.初期Unixシステムの信号メカニズムは比較的単純で原始的であり、その後、実際にいくつかの問題が露呈したため、初期メカニズムに確立された信号を「不信頼信号」と呼び、信号値がSIGRTMIN(SIGRTMIN=32、SIGRTMAX=63)未満の信号はいずれも不信頼信号である.これが「信頼できない信号」の源です.その主な問題は、プロセスが信号を処理するたびに、信号に対する応答をデフォルト動作に設定することである.場合によっては、信号に対するエラー処理を引き起こす.従って、ユーザがこのような操作を望まない場合は、信号処理関数の最後にsignal()をもう一度呼び出し、信号を再インストールする.