【发布时间】: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);
}
}
【问题讨论】: