2011-03-15 44 views
1

大家好 我想要使用的sigaction(),但是沒有成功 這是我的代碼:遇到問題使用的sigaction具有定時信號

int main() 
{ 

struct sigaction act, oact; 
act.sa_handler = (void *)g; 

sigaction(SIGVTALRM,&act,&oact); 

struct itimerval tv; 
tv.it_value.tv_sec = 2; //time of first timer 
tv.it_value.tv_usec = 0; //time of first timer 
tv.it_interval.tv_sec = 2; //time of all timers but the first one 
tv.it_interval.tv_usec = 0; //time of all timers but the first one 

setitimer(ITIMER_VIRTUAL, &tv, NULL); 

for (;;); 
} 

這是克():

void g(void){ 

    printf("I'M NOT IN G!!"); 
    for (;;); 
} 

當我運行代碼時,我陷入了第一次(;;)循環而沒有進入g()。 爲什麼我不能到g()如果我將它定義爲處理信號的函數?

謝謝

+0

您對'sigaction'和'setitimer'的調用返回0(意味着沒有錯誤)?它看起來像這些函數的用法是正確的... – Jonathan 2011-03-15 19:36:01

回答

1

首先,你應該確保輸入struct sigaction結構是乾淨的:

sigemptyset(&act.sa_mask); 
act.sa_flags = 0; 
act.sa_handler = g; 

然後,你應該暫停過程,而不是使用一個for循環「自旋等待」:

sigset_t mask; 
sigprocmask(0, NULL, &mask); 
sigdelset(&mask, SIGVTALRM); 
sigsuspend(&mask); 

最後,你的信號處理程序應該被正確定義,而不是使用printf()函數,這在信號出現時被認爲是不安全的,不應該是用於信號處理程序。相反,它應該設置一個原子標誌:

static volatile sig_atomic_t g_called; 

void g(int sig) { 
    g_called = 1; 
} 
+0

只要非異步信號安全函數調用信號處理程序的'printf'(或其他非異步信號安全函數)是有效和安全的不被信號處理程序中斷。例如,如果信號發生時唯一運行的代碼是'for(;;);'那麼你可以使用你想要的信號處理函數中的任何函數。 – 2011-03-15 20:54:19

+0

'sigsuspend()'通常有意義,但在這種情況下,它將永遠等待,因爲'ITIMER_VIRTUAL'定時器只在用戶模式下執行時運行。 – jilles 2011-03-17 00:46:24

0

最根本的問題是,您使用的是未初始化的sigaction結構。無論是與初始化:

struct sigaction act = {0}; 

或者使用memset調用sigaction之前將其清除。

+0

還有兩個其他問題,標準輸出可能是行緩衝的,所以printf不會顯示 - 其次,不應該在信號處理程序中調用printf,因爲printf不是異步信號安全的(儘管它對於一個像這樣的小測試用例) – nos 2011-03-15 21:01:51

+0

正如我對史蒂夫的回答評論的那樣,只要在調用信號處理函數時沒有其他不是異步信號安全的函數可以執行,那麼調用'printf'在信號處理函數中是完全安全的。這在XSH的2.4.3節末尾由POSIX仔細規定。 – 2011-03-15 22:00:05

+0

你當然對緩衝問題是正確的。 – 2011-03-15 22:00:33