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()をもう一度呼び出し、信号を再インストールする.