2011-12-01 69 views
4

我對處理信號有疑問。 假設如果我們收到SIGINT信號,我們應該打印「Recieved Signal」。如果10秒內處理臨危另一個信號,它應打印「關機」,然後用狀態1.處理多個信號

退出我做了我這樣的代碼:

#include <stdio.h> 
#include <signal.h> 
#include <unistd.h> 

void handler(int); 
void secondhandler(int); 
void alrmhandler(int); 

void alrmhandler (int alrmsig) 
{ 
    alarm(0);  
} 

void secondhandler(int sig) 
{ 
/* after recieving second signal prints shutting down and exit */ 
printf("Shutting Down\n"); 
exit(1); 
} 

void handler (int sig) 
{ 
    /* recieve first SIGINT signal */ 
    printf ("Recieved Signal\n"); 
    /* handle for the alarm function */ 
    signal(SIGALRM, alrmhandler); 
    /* start 10s alarm */ 
    alarm(10); 
    /* catch second SIGINT signal within 10s*/ 
    signal(SIGINT, secondhandler); 

} 



int main(void) 
{ 
    signal(SIGINT, handler); 
     printf("Hello World!\n"); 
    for (;;) 
    { 
    /* infinite loop */ 
    } 

    return 0; 
} 

我試圖與開發的C編譯它++,但失敗了。由於SIGALRM未聲明(首次在此函數中使用)。

無論如何,我想知道的是,如果這段代碼是正確的。我實際上有點不確定alrmhandler()。我應該忽略SIGALRM嗎?

+1

將您的for循環內容更改爲sleep(1);而不是將其設置爲空,以便其他進程也有機會運行。 –

回答

3

如果您在Windows平臺上,您將能夠發送的唯一信號是:SIGABRT,SIGFPE,SIGILL,SIGINT,SIGSEGV或SIGTERM。

+0

好的,thx。但如果我在linux中運行它,它應該工作,不是嗎? – user1075627

+0

@ user1075627:是的,編譯應該在Linux機器上工作,因爲SIGALRM是在'signal.h'中定義的。 –

1

你寫:

什麼,我想知道的是,如果這個代碼是正確的。

不完全。 printf()不是async-signal-safe,所以不應該在信號處理程序中調用,除非您確定這樣做是安全的。它是而不是可以在您提供的代碼中安全地執行此操作。報警()技術通常是種族傾向性的。您的十秒鐘警報可能會在您的二手()函數的中間過期。爲防止這種情況發生,您可能會掩蓋掉信號以便用a more sophisticated signal manipulation function進行補償。

有更多的優雅/靈活的方式來實現你想要的超時,但這可能是一個更適合codereview.stackexchange.com的問題。