在一些程式中,我們需要每隔一段時間執行一個函數。例如每2s,5s,10s分別執行不同的函數。如果有多個定時器,實現這個功能就很簡單,只需分別定時2s,5s,10s即可。但是Linux中只允許一個進程中有一個定時器,怎麼辦呢。可以用以下的方法實現。
首先使用setitimer函數註冊一個1s定時器one_timer,因為1s可以作為被2s,5s,10s整除的單位時間。Setitimer定時時間到達以後會產生SGIALRM訊號,設定SGIALRM的處理函數為multi_timer_manage,定時時間一到便會執行multi_timer_manage函數。
定義一個timers結構體,儲存兩個變數。一個是定時時間,值為想要的時間除以單位時間;另一個是定時時間到時執行的函數。建立timers結構體two_timer, five_timer, ten_timer,並填寫定時時間和需要執行的函數。
multi_timer_manage為實現多個定時器功能的核心部分,在multi_timer_manage中分別將one_timer, two_timer, ten_timer對應的定時時間減一,若為零,則執行對應的函數,並將定時時間複位到初始值重新開始定時。這樣,就實現了多個定時器的功能,詳細代碼如下:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<ctype.h>
#include<string.h>
#include<sys/time.h>
#include<signal.h>
struct itimerval one_timer;
struct timers
{
int interval; //定時時間
void(*handler)(); //處理函數
};
struct timers two_timer;
struct timers five_timer;
struct timers ten_timer;
void multi_timer_manage()
{
printf("\n---");
two_timer.interval--;
if(two_timer.interval==0)
{
two_timer.interval=2;
two_timer.handler();
}
five_timer.interval--;
if(five_timer.interval==0)
{
five_timer.interval=5;
five_timer.handler();
}
ten_timer.interval--;
if(ten_timer.interval==0)
{
ten_timer.interval=10;
ten_timer.handler();
}
}
void two_output()
{
printf("2 ");
}
void five_output()
{
printf("5 ");
}
void ten_output()
{
printf("10 ");
}
void init()
{
one_timer.it_interval.tv_sec=1; //設定單位定時器定時時間
one_timer.it_value.tv_sec=1; //設定單位定時器初始值
setitimer(ITIMER_REAL,&one_timer,NULL); //初始化單位定時器
signal(SIGALRM,multi_timer_manage); //指定單位定時器定時時間到時執行的函數
two_timer.interval=2;
two_timer.handler=two_output;
five_timer.interval=5;
five_timer.handler=five_output;
ten_timer.interval=10;
ten_timer.handler=ten_output;
}
int main()
{
init();
while(1);
}
執行結果如下:
---
---2
---
---2
---5
---2
---
---2
---
---2 5 10
---
---2
---
---2
---5
---2
---
---2
---
---2 5 10
......
可見,每秒都輸出---,每隔2秒輸出2,每隔5秒輸出5,每隔10秒輸出10。