当前位置: 技术问答>linux和unix
请教信号难题
来源: 互联网 发布时间:2015-12-12
本文导语: 在http://community.csdn.net/Expert/topic/5003/5003265.xml?temp=.6551477所说的项目中,有一个新的需求:要求做一个监控进程,当应用进程意外宕掉时能够在最短的时间内能够在最短的时间内将其重新拉起来。我的实现框架是: void...
在http://community.csdn.net/Expert/topic/5003/5003265.xml?temp=.6551477所说的项目中,有一个新的需求:要求做一个监控进程,当应用进程意外宕掉时能够在最短的时间内能够在最短的时间内将其重新拉起来。我的实现框架是:
void main()
{
...
signal ( SIGTERM , HandleExit );
signal ( SIGCHLD , HandleChildDeath );/*检测子进程退出信号,并将其重新启动*/
sighold ( SIGCHLD ) ; /*临时hold子进程退出信号*/
StartAllProg () ; /*启动所有应用进程,方法为fork+exec */
sigrelse ( SIGCHLD ) ; /*release 子进程退出信号*/
...
while ( 1 )
sleep ( 600 );
}
经过测试,效果非常好!无论是子进程core dump还是kill掉子进程,这个监控进程都能立刻将其重新运行起来。
但随之而来的问题也让我非常头痛,比如下面的程序
void catch_child ( int signo )
{
pid_t llpid ;
int status;
while ( 1 )
{
llpid = waitpid ( (pid_t) -1 , &status , WNOHANG ) ;
if ( llpid > 0 )
printf ( "catch process %d exited n" , llpid );
else
break;
}
signal ( SIGCHLD , catch_child );
}
void main( )
{
...
signal ( SIGCHLD , catch_child );
while ( 1 )
{
sleep (1)
if ( fork () == 0 )
{
sleep (3 );
exit (0);
}
}
}
这个程序单独运行时没问题。但通过我做的监控程序运行时 ,父进程就检测不到SIGCHLD信号了,从而产生了大量的僵尸进程。我跟踪过程序 signal ( SIGCHLD , catch_child )是成功的errno也为0,但根本不起作用,用signal ( SIGCHLD , SIG_IGN )也一样。我怀疑问题出在监控进程中的signal ( SIGCHLD , HandleChildDeath );上面,但不知怎么解决?请高手指教!问题解决即给分,帮顶有分!
void main()
{
...
signal ( SIGTERM , HandleExit );
signal ( SIGCHLD , HandleChildDeath );/*检测子进程退出信号,并将其重新启动*/
sighold ( SIGCHLD ) ; /*临时hold子进程退出信号*/
StartAllProg () ; /*启动所有应用进程,方法为fork+exec */
sigrelse ( SIGCHLD ) ; /*release 子进程退出信号*/
...
while ( 1 )
sleep ( 600 );
}
经过测试,效果非常好!无论是子进程core dump还是kill掉子进程,这个监控进程都能立刻将其重新运行起来。
但随之而来的问题也让我非常头痛,比如下面的程序
void catch_child ( int signo )
{
pid_t llpid ;
int status;
while ( 1 )
{
llpid = waitpid ( (pid_t) -1 , &status , WNOHANG ) ;
if ( llpid > 0 )
printf ( "catch process %d exited n" , llpid );
else
break;
}
signal ( SIGCHLD , catch_child );
}
void main( )
{
...
signal ( SIGCHLD , catch_child );
while ( 1 )
{
sleep (1)
if ( fork () == 0 )
{
sleep (3 );
exit (0);
}
}
}
这个程序单独运行时没问题。但通过我做的监控程序运行时 ,父进程就检测不到SIGCHLD信号了,从而产生了大量的僵尸进程。我跟踪过程序 signal ( SIGCHLD , catch_child )是成功的errno也为0,但根本不起作用,用signal ( SIGCHLD , SIG_IGN )也一样。我怀疑问题出在监控进程中的signal ( SIGCHLD , HandleChildDeath );上面,但不知怎么解决?请高手指教!问题解决即给分,帮顶有分!
|
子进程终止,向他的父进程发送SIGCHLD信号。
合理的安排父子关系。 监控程序只有一个儿子进程,也就是被监控程序,被监控程序的所有子进程只向他的父进程也就是被监控进程本身发送SIGCHLD信号。
合理的安排父子关系。 监控程序只有一个儿子进程,也就是被监控程序,被监控程序的所有子进程只向他的父进程也就是被监控进程本身发送SIGCHLD信号。
|
对啊。我说就是这样啊。
子进程会终止会向父进程发送信号。子进程(我上面所说的被监控进程)终止了会给监控进程发信号。子进程创建的进程为子子进程(我上面所说的被监控进程的子进程)终止会给他的父进程(既子进程,也是我上面所说的被监控进程)发信号。
#include
#include
#include
#include
#include
void catch_child(int signo)
{
pid_t llpid ;
int status;
while ( 1 )
{
llpid = waitpid ( (pid_t) -1 , &status , WNOHANG ) ;
if ( llpid > 0 )
printf ( "%d, catch process %d exited n" , getpid(),llpid );
else
break;
}
signal ( SIGCHLD , catch_child );
}
void func()
{
pid_t pid;
signal (SIGCHLD, catch_child);
pid = fork ();
if (pid == 0)
{
printf("child child: pid = %dn", getpid());
exit (0);
}
}
int main()
{
pid_t pid;
signal (SIGCHLD, catch_child);
printf("parent: pid = %dn", getpid());
pid = fork ();
if (pid == 0)
{
printf("child: pid = %dn", getpid());
func();
exit (0);
}
}
parent: pid = 2250
child: pid = 2251
child child: pid = 2252
2251, catch process 2252 exited
2250, catch process 2251 exited
子进程会终止会向父进程发送信号。子进程(我上面所说的被监控进程)终止了会给监控进程发信号。子进程创建的进程为子子进程(我上面所说的被监控进程的子进程)终止会给他的父进程(既子进程,也是我上面所说的被监控进程)发信号。
#include
#include
#include
#include
#include
void catch_child(int signo)
{
pid_t llpid ;
int status;
while ( 1 )
{
llpid = waitpid ( (pid_t) -1 , &status , WNOHANG ) ;
if ( llpid > 0 )
printf ( "%d, catch process %d exited n" , getpid(),llpid );
else
break;
}
signal ( SIGCHLD , catch_child );
}
void func()
{
pid_t pid;
signal (SIGCHLD, catch_child);
pid = fork ();
if (pid == 0)
{
printf("child child: pid = %dn", getpid());
exit (0);
}
}
int main()
{
pid_t pid;
signal (SIGCHLD, catch_child);
printf("parent: pid = %dn", getpid());
pid = fork ();
if (pid == 0)
{
printf("child: pid = %dn", getpid());
func();
exit (0);
}
}
parent: pid = 2250
child: pid = 2251
child child: pid = 2252
2251, catch process 2252 exited
2250, catch process 2251 exited
|
父进程注册的信号处理不会影响子进程的,同样子进程的也不会影响父进程的。
你这可能是信号排队的问题
你这可能是信号排队的问题