如何杀死包括其自身在内的所有进程以及如何正确执行所有进程

时间:2014-02-01 15:08:10

标签: c unix process

我正在尝试使用C语言创建一个在FreeBSD上运行多个进程的程序,主要目标是创建一个Web服务器,根据启动服务器时引入的一些参数,它必须控制活动进程的数量为了创造或摧毁它们。问题是我有一些需要解决的常见问题如下:

- 一旦我创建了一个数字或固定的进程,我可以看到它正确完成,似乎没有更多的进程被创建或销毁,可能是因为while子句但我不知道如何解决它。

- 如果我发送SIGTERM,则所有子进程都会完成,但父进程会完成。

以下是代码:

int
main (int argc, char **argv)
{
  /* Here I stablish the routine of signal treatment, including SIGCHLD,
   * and also "starts" the parent process */
  signal (SIGINT, manager_SIGINT);
  signal (SIGTERM, manager_SIGTERM);
  signal (SIGCHLD, manager_SIGCHLD);

  while (end_program != 1)
    {
      sleep (1);
      //Here I control the number of processes and create or destroy as needed        

      /*Here I stablish the signals for the child processes, where they "start" */

      signal (SIGCHLD, SIG_IGN);
      signal (SIGTERM, manager_child_SIGTERM);
      signal (SIGTERM, manager_SIGTERM);
      while (!end_process)
        {
          //Child processes code is here
        }                       //end while(!end_process)
    }                           //end while(!end_program)
  /* Here I send to all processes the SIGTERM signal and wait its execution*/
  killpg (0, SIGTERM);
  wait (NULL);
  return (0);
}

先谢谢Javier

编辑:这是我处理信号的方式

void manager_SIGINT(int signal)
{  
end_program = 1;
}

void manager_SIGTERM(int signal)
{   
end_program = 1;
}

void manager_child_SIGTERM(int signal)
{
end_process=1;
}

void manager_SIGCHLD(int signal)
{
pid_t child_pid;
int e;
child_killed_num=0;
do
{
    child_pid=wait3(&e,WNOHANG,NULL);
    if((child_pid>(pid_t)0)&&(WIFEXITED(e)||WIFSIGNALED(e)))
    {
        child_killed[child_killed_num]=child_pid;
        child_killed_num++; 
    }
}while(child_pid>(pid_t)0);
end_process=1;
}

编辑2:这就是我做叉子的方式:

void create_child(int position,ChildTable *table)
{
pid_t child_pid;
    /*Here I block SIGCHLD in something wrong happen when doing fork()*/
sigset_t mask;
sigset_t orig_mask;
struct sigaction act;
memset (&act, 0, sizeof(act));
act.sa_handler = manager_SIGCHLD;
sigaction(SIGCHLD,&act,NULL);
sigemptyset (&mask);
sigaddset (&mask, SIGCHLD);
int is_member=sigismember(&mask,SIGCHLD);
if(is_member==1)
{
    sigprocmask(SIG_BLOCK, &mask, &orig_mask);

fflush(NULL);
switch(child_pid=fork())
{
    case 0:
    {

    }
    default:
    {
        table[position].child.pid=child_pid;
    }
    case -1:
    {
        break;
    }
}
    /*Now that pid has been written it is possible to unblock SIGCHLD*/
    sigdelset (&mask, SIGCHLD);
    sigprocmask(SIG_UNBLOCK, &mask, &orig_mask);
}
}

1 个答案:

答案 0 :(得分:0)

您的程序中没有fork(),那么它如何启动子进程?除了信号处理之外,您的示例中似乎没有任何内容,并且您已删除了信号处理程序。

此问题的常规答案是在fork()编辑时维护子PID的数组,并将其从wait中的数组中移除(并执行SIGCHLD)处理程序。然后在退出时,您只需要向阵列中的进程发送kill信号。

如果你想获得幻想,你也可以

  1. 处理父项的意外终止(例如,确保父项存活的子项,可能是通过查找意外关闭pipe())并退出(如果是这样)。

  2. 写出一个包含父级PID的PID文件,以便init脚本可以轻松处理将其删除。

  3. 然而,在你想到之前,我建议你做一些基本的事情。

    我建议你去/借一些Stephens的副本:http://tinyurl.com/stephensfaq