linux幾種定時函數的使用


Linux定時函數介紹:

  在程序開發過程中,我們時不時要用到一些定時器,通常如果時間精度要求不高,可以使用sleep,uslepp函數讓進程睡眠一段時間來實現定時,

前者單位為秒(s),后者為微妙(us);但有時候我們又不想讓進程睡眠阻塞在哪兒,我們需要進程正常執行,當到達規定的時間時再去執行相應的操作,

在linux下面我們一般使用alarm函數跟setitimer函數來實現定時功能;

下面對這兩個函數進行詳細分析:

(1)alarm函數

  alarm也稱為鬧鍾函數,它可以在進程中設置一個定時器,當定時器指定的時間到時,它向進程發送SIGALRM信號;

alarm函數原型如下:

1 unsigned int alarm(unsigned int seconds);
2 
3 //seconds 為指定的秒數
返回值:
成功:如果調用此alarm()前,進程已經設置了鬧鍾時間,則返回上一個鬧鍾時間的剩余時間,否則返回0。
出錯:-1
下面是alarm()函數的簡單例子:
 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <unistd.h>
 4 #include <signal.h>
 5 
 6 void func()
 7 {
 8     printf("this is func\n");
 9 }
10 
11 int main()
12 {
13 
14     signal(SIGALRM, func); //2s后要執行的函數
15     alarm(2);//設置定時2s
16 
17     while (1);
18 
19     return 0;
20 }

(2)setitimer()函數

  在linux下如果對定時要求不太精確的話,使用alarm()和signal()就行了,但是如果想要實現精度較高的定時功能的話,就要使用setitimer函數。

  setitimer()為Linux的API,並非C語言的Standard Library,setitimer()有兩個功能,一是指定一段時間后,才執行某個function,二是每間格一段時間就執行某個function;

  Linux為每個任務安排了3個內部定時器:

ITIMER_REAL:實時定時器,不管進程在何種模式下運行(甚至在進程被掛起時),它總在計數。定時到達,向進程發送SIGALRM信號。

ITIMER_VIRTUAL:這個不是實時定時器,當進程在用戶模式(即程序執行時)計算進程執行的時間。定時到達后向該進程發送SIGVTALRM信號。 

ITIMER_PROF:進程在用戶模式(即程序執行時)和核心模式(即進程調度用時)均計數。定時到達產生SIGPROF信號。ITIMER_PROF記錄的時間比ITIMER_VIRTUAL多了進程調度所花的時間。

定時器在初始化是,被賦予一個初始值,隨時間遞減,遞減至0后發出信號,同時恢復初始值。在任務中,我們可以一種或者全部三種定時器,但同一時刻同一類型的定時器只能使用一個。

setitimer函數原型如下:

 1  #include <sys/time.h>
 2 
 3        int setitimer(int which, const struct itimerval *new_value,
 4                      struct itimerval *old_value);
 5 
 6  Timer values are defined by the following structures:
 7 
 8            struct itimerval {
 9                struct timeval it_interval; /* next value */
10                struct timeval it_value;    /* current value */
11            };
12 
13            struct timeval {
14                time_t      tv_sec;         /* seconds */
15                suseconds_t tv_usec;        /* microseconds */
16            };

  it_interval用來指定每隔多長時間執行任務, it_value用來保存當前時間離執行任務還有多長時間。比如說, 你指定it_interval為2秒(微秒為0),開始的時候我們把it_value的時間也設定為2秒(微秒為0),當過了一秒, it_value就減少一個為1, 再過1秒,則it_value又減少1,變為0,這個時候發出信號(告訴用戶時間到了,可以執行任務了),並且系統自動把it_value的時間重置為 it_interval的值,即2秒,再重新計數

下面是setitimer簡單實例:

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <stdlib.h>
 4 #include <signal.h>
 5 #include <sys/time.h>
 6 
 7 void test_func()
 8 {
 9     static count = 0;
10 
11     printf("count is %d\n", count++);
12 }
13 
14 void init_sigaction()
15 {
16     struct sigaction act;
17           
18     act.sa_handler = test_func; //設置處理信號的函數
19     act.sa_flags  = 0;
20 
21     sigemptyset(&act.sa_mask);
22     sigaction(SIGPROF, &act, NULL);//時間到發送SIGROF信號
23 }
24 
25 void init_time()
26 {
27     struct itimerval val;
28          
29     val.it_value.tv_sec = 1; //1秒后啟用定時器
30     val.it_value.tv_usec = 0;
31 
32     val.it_interval = val.it_value; //定時器間隔為1s
33 
34     setitimer(ITIMER_PROF, &val, NULL);
35 }
36 
37 int main(int argc, char **argv)
38 {
39 
40     init_sigaction();
41     init_time();
42 
43     while(1);
44 
45     return 0;
46 }

可以看出每個一秒輸出一個count的值:

下面是運行結果:

[root@localhost 5th]# ./test
count is 0
count is 1
count is 2
count is 3
count is 4
count is 5
count is 6
count is 7
count is 8
count is 9

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM