【问题标题】:Why can't the signal handler in the child process be triggered?为什么不能触发子进程中的信号处理器?
【发布时间】:2017-06-04 03:11:17
【问题描述】:

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

我想出的设计是: 父级为 SIGALRM 注册一个信号处理程序。然后它派生一个将触发 SIGALRM 的子进程并继续调用 fgets。 SIGALRM 将触发终止父进程的处理程序。但是当我在 ubuntu 14.04 64 位上执行此操作时,不会触发处理程序,程序只会等待用户永远输入 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;                                                                     
}      

~

【问题讨论】:

    标签: c linux ubuntu process signals


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

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

      int kill(pid_t pid, int sig);

      修复:

      kill(getppid(), SIGKILL); 
      

      另外,您的孩子在信号发出之前终止执行,您必须在调用 alarm() 后添加 sleep() 以使其等待:

      alarm(1);
      sleep(2);
      

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

      【讨论】:

      • 感谢您的建议!我有一个设计问题:要实现这个超时功能,有没有其他方法来设计这个程序而不是使用 kill?它使程序不稳定。即使在应用您的修复后,该程序的行为也符合我的要求。但有时系统只是自动注销。我认为我使用 kill 的方式带来了一些不稳定因素。
      • 我将创建另一个问题。但我会根据现有设计为您提供解决方案。
      • 但我不能同意令人讨厌的部分。我不知道 kill 是否会自动将我从系统中注销。如果你真的想锤这个。你能解释一下吗?因此,与其为一些神秘的系统级别的东西而烦恼。我宁愿花时间创造一个合适的设计。但我愿意接受有关此注销问题的见解。
      • 这是我的朋友,非常感谢您的回答:) stackoverflow.com/questions/44350650/…
      • 其实。我创建了一个 bash 脚本来继续运行更新的程序。它现在不会自动注销。我不知道它之前为什么会出现这个问题。
      猜你喜欢
      • 1970-01-01
      • 2018-03-19
      • 2017-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      相关资源
      最近更新 更多