2011-03-13 70 views
2

如果我們使用sigaction來定義信號處理程序,那麼爲什麼我們不需要重置處理程序?如果我們使用signal(sig_no,handler_func)那麼我們必須重置它。爲什麼是這樣?sigaction - 爲什麼我們不需要重置處理程序?

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

void func(int sig) 
{ 
printf("caught signal:%d\n",sig); 
// Not needed to reset handler. Why? 
} 

int main() 
{ 
struct sigaction sa; 

sa.sa_handler=(void*)func; 
sigaction(SIGRTMIN,&sa,NULL); 
kill(0,SIGRTMIN); 
kill(0,SIGRTMIN); 
kill(0,SIGRTMIN); 
} 
Output: 
[[email protected] signals]# ./a.out 
    caught signal:34 
    caught signal:34 
    caught signal:34 (3 times signal caught by same handler without resetting handler) 

回答

5

除非你指定的標誌SA_RESETHAND,性格沒有改變(因此不需要重新設置)如果你是

設置sa.sa_flags = SA_RESETHAND你需要重新設置,因爲處置將被重置爲SIG_DFL(這是signal()發生的情況)

基本上,您的問題的答案是「因爲這就是sigaction的工作原理,它的行爲與信號不同。

+0

謝謝,非常好,信息豐富。 – kingsmasher1 2011-03-13 17:36:22

6

真正的原因可追溯到幾十年前。原來的signal()沒有重裝處理器。它也沒有重啓中斷的系統調用。 BSD傢伙決定有一個更「可靠」的signal(),所以他們改變了這種語義。

由於System V和BSD行爲如此不同,POSIX委託人決定引入一個新的系統調用sigaction(),並帶有參數來修改其行爲。所以sigaction()存在的全部原因是使用跨Unix變體表現相同的代碼的信號。

(注意的signal()的bahaviour可以改變使用相同的libc時,例如即使,glibc的默認使用BSD行爲,SYSV行爲定義_XOPEN_SOURCE時)。

+0

當'_XOPEN_SOURCE'設置爲一個非常舊的版本時,我希望它只使用SYSV行爲,因爲所有的現代版本都允許(更明智的)BSD行爲,它應該被保留。 – 2011-03-14 02:22:20

+0

感謝您瞭解新事物。 – kingsmasher1 2011-03-14 07:46:26

相關問題