【问题标题】:Capture signal in C and kill all children在C中捕获信号并杀死所有孩子
【发布时间】:2023-12-29 06:45:02
【问题描述】:

我需要捕获 CTRL+C 并完成子进程,主进程必须等到完成它的东西,然后程序必须完成。 这是我的代码:

 void sigint_handler()
{
    /*do something*/
    printf("killing process %d\n",getpid());
    exit(0);
}

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


  printf ("This is the parent. PID=%d\n",getpid ());

  int num_children = 4;

  int i;

  while (1){

  for (i=0; i<num_children ;i++){

   if (fork()==0){

    printf ("This is children %d\n",getpid()); 

    sleep(1);

    exit(0);

   }

  }

  //Rest Parent code
  sleep (1);

  printf ("This is the parent again %d, children should have finished\n",getpid());

  //Do stuff

  }

}

这是输出:

This is the parent. PID=19317
This is children 19318
This is children 19319
This is children 19321
This is children 19320
^Ckilling process 19321
killing process 19320
killing process 19317
killing process 19318
killing process 19319

我该如何处理这个¿?我不想杀父母,只杀孩子,提前谢谢你!

【问题讨论】:

  • 永远不要在信号处理程序中使用 printf。它不是可重入的。

标签: c signals fork kill-process


【解决方案1】:

在信号处理程序kill 中仅子进程。在父进程wait 让子进程在退出之前退出。

【讨论】:

  • 我不得不用另一个答案来回答你(就在下面)1条评论还不够
【解决方案2】:

进行此更改,

  for (i=0; i<num_children ;i++){

   if (fork()==0){
signal(SIGINT, sigint_handler);
    printf ("This is children %d\n",getpid()); 

    sleep(1);

    exit(0);

   }

  }

只有子进程满足if (fork()==0) 条件,因此只有子进程将被注册以捕获信号并退出。

【讨论】:

    【解决方案3】:

    现在这样好多了:

        void sigint_handler()
        {
            /*do something*/
            printf("killing process %d\n",getpid());
            exit(0);
        }
    
        int main ()
        {
            int num_children = 4;
            int i, pid, status;
            printf ("This is the parent. PID=%d\n", getpid());
    
            while (1) {
                for (i = 0; i < num_children; i++) {
                    if ((pid = fork()) == 0) {
                        signal(SIGINT, sigint_handler);
                        printf("This is children %d\n", getpid()); 
                        sleep(1);
                        exit(0);
                    }
                }
    
                // Rest Parent code
                sleep (1);
                waitpid(pid, &status, 0); 
                printf ("This is the parent again %d, children should have finished\n", getpid());
            }
        }
    

    它首先杀死了孩子,但waitpid似乎什么都不做,这是输出:

    This is the parent. PID=20048
    This is children 20049
    This is children 20050
    This is children 20051
    This is children 20052
    This is the parent again 20048, children should have finished
    This is children 20053
    This is children 20054
    This is children 20056
    This is children 20055
    ^Ckilling process 20056
    killing process 20055
    killing process 20053
    killing process 20054
    

    我想要的是在最后打印:这又是父母 20048,孩子们应该已经完成​​然后完成。 非常感谢

    【讨论】: