天天看點

linux之alarm函數

1. alarm函數

[cpp]  view plain  copy

  1. [1] 引用頭檔案:#include <unistd.h>;  
  2. [2] 函數标準式:unsigned int alarm(unsigned int seconds);  
  3. [3] 功能與作用:alarm()函數的主要功能是設定信号傳送鬧鐘,即用來設定信号SIGALRM在經過參數seconds秒數後發送給目前的程序。如果未設定信号SIGALARM的處理函數,那麼alarm()預設處理終止程序。  
  4. [4] 函數傳回值:如果在seconds秒内再次調用了alarm函數設定了新的鬧鐘,則後面定時器的設定将覆寫前面的設定,即之前設定的秒數被新的鬧鐘時間取代;當參數seconds為0時,之前設定的定時器鬧鐘将被取消,并将剩下的時間傳回。  

2. 測試

原文的測試環境是RedHat Linux5.3,本人在Ubuntu 14.04中再次進行了測試。測試結果與原作者一緻。

了解了alarm()函數的功能特性和傳回值的特性後,我們就可以對其測試。測試方向有兩個:其一,測試正常隻單獨存在一個鬧鐘函數alarm()的程式;其二,測試程式中包含多個alarm()鬧鐘函數。是以整理了下面幾個程式,通過比較學習更有助于了解。測試環境是RedHat Linux5.3,GCC編譯調試。

2.1 alarm()測試1.1

[cpp]  view plain  copy

  1. #include <unistd.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <signal.h>  
  5. void sig_alarm()   
  6. {   
  7.   exit(0);   
  8. }  
  9. int main(int argc, char *argv[])   
  10. {   
  11.   signal(SIGALRM, sig_alarm);   
  12.   alarm(10);   
  13.   sleep(15);   
  14.   printf("Hello World!\n");   
  15.   return 0;   
  16. }  
linux之alarm函數

程式分析:在檔案test1.c中,定義了一個時鐘alarm(10),它的作用是讓信号SIGALRM在經過10秒後傳送給目前main()所在程序;接着又定義了sleep(15),它的作用是讓執行挂起15秒的時間。是以當main()程式挂起10秒鐘時,signal函數調用SIGALRM信号的處理函數sig_alarm,并且sig_alarm執行exit(0)使得程式直接退出。是以,printf("Hello World!\n")語句是沒有被執行的。

2.2 alarm()測試1.2

[cpp]  view plain  copy

  1. #include <unistd.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <signal.h>  
  5. void sig_alarm()   
  6. {   
  7.   exit(0);   
  8. }   
  9. int main(int argc, char *argv[])   
  10. {   
  11.   signal(SIGALRM, sig_alarm);   
  12.   alarm(10);   
  13.   sleep(5);   
  14.   printf("Hello World!\n");   
  15.   return 0;   
  16. }  
linux之alarm函數

程式分析:與test1.c檔案不同的是,在檔案test2.c中延時函數為sleep(5),即執行挂起5秒的時間。是以當main()程式挂起5秒鐘時,由于還沒到達設定的鬧鐘10秒,那麼main就執行下面的printf("Hello World!\n")語句;緊接着又執行下面的return 0語句,進而直接退出程式。是以,整個test2.c檔案輸出的内容為:Hello World!。

2.3 alarm()測試2

[cpp]  view plain  copy

  1. #include <unistd.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <signal.h>  
  5. void handler()  
  6. {  
  7.   printf("hello\n");  
  8. }  
  9. void main()  
  10. {  
  11.   int i;  
  12.   signal(SIGALRM, handler);  
  13.   alarm(5);  
  14.   for(i = 1; i < 7; i++)  
  15.   {  
  16.     printf("sleep %d ...\n", i);  
  17.     sleep(1);  
  18.   }  
  19. }  
linux之alarm函數

程式分析:在檔案test3.c中,定義時鐘alarm(5),而main()函數中主要是一個for循環輸出語句。當main函數執行到i=5時,for循環先執行printf("sleep %d ...\n", 5)語句輸出"sleep 5 ...",然後執行sleep(1)語句。此時已經到達鬧鐘時間5秒,是以會把信号SIGALRM傳送給目前main()函數程序;接着調用SIGALRM信号的處理函數handler,進而輸出"hello",然後又傳回到sleep(1)這個點;最後for循環執行i=6,輸出"sleep 6",最終延時1秒後結束整個程式。

以上三個程式都隻包含一個alarm()鬧鐘函數,下面兩個程式包含兩個alarm()。并且為了更為真切的觀察包含alarm()鬧鐘函數的程式的執行過程,程式通過調用系統列印輸出目前時間,通過時間差來進一步了解。

2.4 alarm()測試3.1

[cpp]  view plain  copy

  1. #include <unistd.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <signal.h>  
  5. static void sig_alrm(int signo);  
  6. int main(void)  
  7. {  
  8.   signal(SIGALRM,sig_alrm);  
  9.   system("date");  
  10.   alarm(20);  
  11.   sleep(5);  
  12.   printf("%d\n",alarm(15));  
  13.   pause();  
  14. }  
  15. static void sig_alrm(int signo){  
  16.   system("date");  
  17.   return;  
  18. }  
linux之alarm函數

程式分析:在test4.c的main()函數中,先設定了一個鬧鐘函數alarm(20),即在20秒時将SIGALRM信号傳送送給目前程序;然後又定義了一個延時函數sleep(5),接着又定義了一個鬧鐘函數alarm(15),它的作用是清除前面設定的鬧鐘alarm(20)并傳回剩餘的時間20-5=15秒。是以,程式先執行system("date")語句輸出目前時間;然後程序休眠5秒後,程式執行輸出語句printf("%d\n",alarm(15)),由于alarm(15)先傳回15秒,即列印輸出15;接着程式執行pause()函數,使目前程序處于挂起狀态,直到捕捉到一個信号;當再過15秒後,SIGALARM信号的處理函數sig_alrm執行system("date")語句輸出目前時間;最後pause終止程序。是以,整個程式執行的時間為5+15=20秒。

2.5 alarm()測試3.2

[cpp]  view plain  copy

  1. #include <unistd.h>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <signal.h>  
  5. static void sig_alrm(int signo);  
  6. int main(void)  
  7. {  
  8.   signal(SIGALRM,sig_alrm);  
  9.   system("date");  
  10.   alarm(20);  
  11.   sleep(5);  
  12.   printf("%d\n",alarm(5));  
  13.   pause();  
  14. }  
  15. static void sig_alrm(int signo){  
  16.   system("date");  
  17.   return;  
  18. }  
linux之alarm函數

程式分析:與test4.c檔案不同的是,在檔案test5.c中鬧鐘函數為alarm(5)。是以,整個程式執行的時間為5+5=10秒。值得注意的是,

alarm(0)

表示清除之前設定的鬧鐘信号,并傳回0。因為,如果這裡把alarm(5)改成alarm(0),那麼整個程式執行的時間為5+0=5秒。

最後:需要注意的是,原作者在文章中進行了精确的時間計算,而程式運作的結果也與作者的計算一緻,但即使如此,精确的結果也是不可信的和計算精确的結果也是不可行的。在某些條件下,我們實際花費和等待的時間很有可能比程式設定的時間要長,而且1秒對于現代的作業系統來說,實在是太長了。

原文連結:https://blog.csdn.net/u010155023/article/details/51984602

繼續閱讀