2014-05-19 91 views
1

我試圖讓程序在收到信號後重新載入本身。我有這樣的代碼執行後無法捕捉信號

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


void signal_callback_handler(int signum){ 

    printf("Caught signal %d\n",signum); 

    execv("./test", NULL); //reexec myself 
} 

int main() 
{ 
    signal(SIGINT, signal_callback_handler); 


    printf("Program STARTED\n"); 

     while(1){ 
     printf("Program processing stuff here.\n"); 
     sleep(1); 
    } 
    return EXIT_SUCCESS; 
} 

的問題是,高管程序後,就忽略信號,而不是調用信號處理程序。 輸出:

Program STARTED 
Program processing stuff here. 
Program processing stuff here. 
^CCaught signal 2 
Program STARTED 
Program processing stuff here. 
^C^CProgram processing stuff here. 
^C^C^C^C^CProgram processing stuff here. 
^C^CProgram processing stuff here. 

如何使Exec之後信號處理工作?

+0

可能重複的[是否有可能信號處理程序生存後「執行」?](http://stackoverflow.com/questions/2333637/is-it-possible-to-signal-handler-to-survive-後執行) –

+0

我已經讀過這個問題。我需要相反的事情 - 我期望exec將取代進程,然後signal()將設置新的信號處理程序,我不需要保留舊的處理程序,程序將只是重新啓動它們,但此重新初始化不起作用 – user1940679

+0

@MartinR不,這不是重複的。 –

回答

2

信號掩碼是通過exec繼承的,SIGINT在調用信號處理程序期間被阻止,它調用execve。因此,您的重新執行的映像是在SIGINT被阻止的情況下啓動的。

如果與strace的過程中,你會看到你的signal呼叫變成類似:

3143 rt_sigaction(SIGINT, {0xabcd, [INT], SA_RESTORER|SA_RESTART, 0xabcd}, {SIG_DFL, [], 0}, 8) = 0 
            ^^^^^ 
             | 
             +--- SIGINT is blocked during handler! 

sigaction將讓您欣賞到信號處理更精細的控制,並is recommended over signal

+0

使用了'sa_flags = SA_NOMASK'的sigaction,現在它可以工作。謝謝 – user1940679

1

Yor信號在執行信號處理程序期間被阻止,並且信號掩碼通過exec繼承。您需要明確重置它。

這裏存在一個潛在的問題,如果您在處理程序內部解除阻塞,並且您有另一個待處理的信號,它將立即傳遞,導致處理程序再次執行。這應該是罕見的,但它可能發生。更糟糕的是,如果你在重新執行的進程中解鎖,並且你有一個待處理的信號,你可能會將它傳送到重新執行的進程,可能會導致它被終止。因此,首先在「孩子」中設置一個處理程序,然後解鎖。