我正在尝试使用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);
}
}
答案 0 :(得分:0)
您的程序中没有fork()
,那么它如何启动子进程?除了信号处理之外,您的示例中似乎没有任何内容,并且您已删除了信号处理程序。
此问题的常规答案是在fork()
编辑时维护子PID的数组,并将其从wait
中的数组中移除(并执行SIGCHLD
)处理程序。然后在退出时,您只需要向阵列中的进程发送kill
信号。
如果你想获得幻想,你也可以
处理父项的意外终止(例如,确保父项存活的子项,可能是通过查找意外关闭pipe()
)并退出(如果是这样)。
写出一个包含父级PID的PID文件,以便init脚本可以轻松处理将其删除。
然而,在你想到之前,我建议你做一些基本的事情。
我建议你去/借一些Stephens的副本:http://tinyurl.com/stephensfaq