杀死信号的例子

时间:2011-06-09 01:37:43

标签: c unix signals kill

我正在尝试这个例子:http://www.cs.cf.ac.uk/Dave/C/node24.html

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

void sighup(); /* routines child will call upon sigtrap */
void sigint();
void sigquit();

main() { 
 int pid;

 /* get child process */

 if ((pid = fork()) < 0) {
    perror("fork");
    exit(1);
 }

if (pid == 0) { /* child */
   printf("\nI am the new child!\n\n");
       signal(SIGHUP,sighup); /* set function calls */
       signal(SIGINT,sigint);
       signal(SIGQUIT, sigquit);
       printf("\nChild going to loop...\n\n");
      for(;;); /* loop for ever */
 }
else /* parent */
 {  /* pid hold id of child */
   printf("\nPARENT: sending SIGHUP\n\n");
   kill(pid,SIGHUP);
   sleep(3); /* pause for 3 secs */
   printf("\nPARENT: sending SIGINT\n\n");
   kill(pid,SIGINT);
   sleep(3); /* pause for 3 secs */
   printf("\nPARENT: sending SIGQUIT\n\n");
   kill(pid,SIGQUIT);
   sleep(3);
 }
}

void sighup() {
   signal(SIGHUP,sighup); /* reset signal */
   printf("CHILD: I have received a SIGHUP\n");
}

void sigint() {
    signal(SIGINT,sigint); /* reset signal */
    printf("CHILD: I have received a SIGINT\n");
}

void sigquit() {
  printf("My DADDY has Killed me!!!\n");
  exit(0);
}

但是我没有看到子进程的任何输出。

这是预期的行为吗?如果是这样;为什么呢?

非常感谢!

2 个答案:

答案 0 :(得分:2)

您的代码存在重大竞争条件。在父发送信号之前,您无法确保孩子已完成呼叫signal。您需要使用某种同步原语使父级等待子级安装处理程序,或者您需要在分叉之前安装信号处理程序,以便子级继承它们。

这是我知道的最简单的方式来同步这样的过程:

  1. 在分叉之前,请致电pipe(p)以创建烟斗。
  2. fork()
  3. 在父级close(p[1]);(写作结束)和read(p[0], &dummy, 1);
  4. 安装信号处理程序后,孩子close(p[0]);close(p[1]);
  5. 当父项从read返回时,您可以确定该子项已设置其信号处理程序。此时您也可以在父母close(p[0]);
  6. 编辑2:也许是一种更好更简单的方法:

    1. 在分叉之前,请拨打sigprocmask以阻止所有信号并保存旧信号掩码。
    2. 在父母中,在分支恢复原始信号掩码后立即再次呼叫sigprocmask
    3. 在孩子中,在安装信号处理程序后立即拨打sigprocmask以恢复原始信号掩码。

答案 1 :(得分:0)

你应该使用getpid()而不是pid()。