2014-09-06 98 views
0

父进程分叉两个子进程,分别代替SIGUSR1SIGUSR2信号。发送和处理带子进程信号的问题C

父进程取代SIGINT信号,在捕获它时分别发送SIGUSR1SIGUSR2给它的孩子。

时按Ctrl-C应该是预期的输出:

Ctrl+C is pressed。 
received SIGUSR1 signal 
received SIGUSR2 signal 

但在按Ctrl-C我有

Ctrl+C is pressed。 

我不知道为什么sig_handler_1sig_handler_2不excuted 。

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <signal.h> 
void fun_ctrl_c(int); 
void sig_handler_1(int); 
void sig_handler_2(int); 
pid_t pid1; 
pid_t pid2; 
int status; 

int main() { 
    pid1 = fork(); 
    if (pid1 == 0) { // child 1 
     // avoid to be killed 
     (void) signal(SIGINT, SIG_IGN); 
     // replace SIGUSR1 
     (void) signal(SIGUSR1, sig_handler_1); 
     raise(SIGSTOP); 
    } else { 
     pid2 = fork(); 
     if (pid2 == 0) { // child 2 
      // avoid to be killed 
      (void) signal(SIGINT, SIG_IGN); 
      // replace SIGUSR2 
      (void) signal(SIGUSR2, sig_handler_2); 
      raise(SIGSTOP); 
     } else { // parent 
      (void) signal(SIGINT, fun_ctrl_c); 
      waitpid(-1, &status, 0); 
     } 
    } 
    return 0; 
} 

void fun_ctrl_c(int) 
{ 
    printf("Ctrl+C is pressed。\n"); 
    kill(pid1 ,SIGUSR1); 
    kill(pid2 ,SIGUSR2); 
    (void) signal(SIGINT, SIG_DFL); 
} 

void sig_handler_1(int) 
{ 
    printf("received SIGUSR1 signal\n"); 
} 

void sig_handler_2(int) 
{ 
    printf("received SIGUSR2 signal\n"); 
} 
+1

使用'替换'不是通常的术语。你似乎在'处理'这些信号,或者'用不同的信号处理器来代替'。 – 2014-09-06 19:37:52

回答

1

你的问题是,你的子进程raise(SIGSTOP);,所以他们停止,并且不能在所有的信号作出反应。

将其替换为pause(); - 代码即可使用。

#include <signal.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/wait.h> 
#include <unistd.h> 

void fun_ctrl_c(int); 
void sig_handler_1(int); 
void sig_handler_2(int); 

pid_t pid1; 
pid_t pid2; 

int main(void) 
{ 
    pid1 = fork(); 
    if (pid1 == 0) 
    { 
     (void) signal(SIGINT, SIG_IGN); 
     (void) signal(SIGUSR1, sig_handler_1); 
     pause(); 
     printf("PID %d exiting\n", (int)getpid()); 
    } 
    else if ((pid2 = fork()) == 0) 
     { 
      (void) signal(SIGINT, SIG_IGN); 
      (void) signal(SIGUSR2, sig_handler_2); 
      pause(); 
      printf("PID %d exiting\n", (int)getpid()); 
     } 
     else 
     { 
      (void) signal(SIGINT, fun_ctrl_c); 
      int status; 
      int pid; 
      printf("Interrupt me!\n"); 
      while ((pid = waitpid(-1, &status, 0)) != -1) 
       printf("Child %d exited with status 0x%.4X\n", pid, status); 
      printf("Parent %d exiting\n", (int)getpid()); 
     } 
    return 0; 
} 

void fun_ctrl_c(int signum) 
{ 
    printf("Ctrl+C is pressed。Received SIGINT (%d) signal\n", signum); 
    kill(pid1, SIGUSR1); 
    kill(pid2, SIGUSR2); 
    (void) signal(SIGINT, SIG_DFL); 
} 

void sig_handler_1(int signum) 
{ 
    printf("received SIGUSR1 (%d) signal\n", signum); 
} 

void sig_handler_2(int signum) 
{ 
    printf("received SIGUSR2 (%d) signal\n", signum); 
} 

采样运行(我称为程序sigintusr12):

$ ./sigintusr12 
Interrupt me! 
^CCtrl+C is pressed。Received SIGINT (2) signal 
received SIGUSR2 (31) signal 
received SIGUSR1 (30) signal 
PID 31184 exiting 
PID 31183 exiting 
Child 31184 exited with status 0x0000 
Child 31183 exited with status 0x0000 
Parent 31182 exiting 
$ 

请注意,你不应该严格使用printf()(和许多其他功能,特别是那些可能需要分配内存)在信号处理程序中。在这里它可以正常工作,但这不是一个好的做法。有关更多信息,请参阅How to avoid using printf() in a signal handler?