为什么不能触发子进程中的信号处理程序?

时间:2017-06-04 03:11:17

标签: c linux ubuntu process signals

我的目的是为fgets创造1秒的时间。如果在1秒内未收到任何输入,则程序终止。

我提出的设计是: 父寄存器为SIGALRM注册信号处理程序。然后它会分叉一个触发SIGALRM的孩子,然后继续调用fgets。 SIGALRM将触发杀死父进程的处理程序。但是当我在64位的ubuntu 14.04上执行此操作时,处理程序不会被触发,程序只是等待用户永远输入fgets。

为什么会发生这种情况?我该如何解决这个问题?

#include "csapp.h"                                                              

void handler() {                                                                
  printf("lazy man\n");                                                         
  kill(SIGKILL, getppid());                                                     
  exit(0);                                                                      
}                                                                               

int main() {                                                                    
  char buf[100];                                                                
  signal(SIGALRM, handler);                                                     
  pid_t pid;                                                                    
  if ((pid = fork()) == 0) {                                                    
    alarm(1);                                                                   
  } else {                                                                      
    fgets(buf, 100, stdin);                                                     
    printf("%s", buf);                                                          
  }                                                                             
  return 0;                                                                     
}      

2 个答案:

答案 0 :(得分:1)

如果您花时间阅读 kill()手册,您会发现错过了参数的顺序。

  

int kill(pid_t pid,int sig);

修正:

kill(getppid(), SIGKILL); 

另外,您的孩子在信号提升之前终止执行,您必须在致电sleep()后添加alarm()以使其等待:

alarm(1);
sleep(2);

最后,printf()在信号处理程序list of safe function中不安全。

答案 1 :(得分:0)

这种分叉和杀戮似乎是错误的。只需设置警报,为SIGALRM注册一个空信号处理程序,然后检查fgets()的返回值 - 如果失败,检查errno == EINTR;如果它 - 它被信号打断了。