【问题标题】:How to kill all processes including itself and how to execute all of them properly如何杀死包括自身在内的所有进程以及如何正确执行所有进程
【发布时间】:2014-02-01 15:08:10
【问题描述】:

我正在尝试用 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);
}

非常感谢,哈维尔

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

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);
}
}

【问题讨论】:

    标签: c unix process


    【解决方案1】:

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

    这个问题的常规答案是在fork()-ed 时维护一个子PID 数组,并在SIGCHLD 处理程序中将它们从数组中删除(并执行wait)。然后在退出时,您只需向数组中的进程发送kill 信号。

    如果你想变得花哨,你也可以

    1. 处理父级的意外终止(例如,通过子级确保父级还活着,也许通过寻找pipe() 的意外关闭),如果是,则退出。

    2. 写出一个包含父 PID 的 PID 文件,以便 init 脚本可以轻松处理杀死它。

    不过,在你变得花哨之前,我建议你先做一些基本的事情。

    我建议你去拿/借一本斯蒂芬斯:http://tinyurl.com/stephensfaq

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-20
      • 1970-01-01
      • 1970-01-01
      • 2011-02-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多