背景知识:
子进程先于父进程结束时,会给父进程发送SIGCHLD信号
如果
1、父进程没有忽略SGICHLD信号;
或者
2、父进程没有调用wait或waitpid函数。
那么子进程将僵死。
(
在2.6内核,只要父进程显式忽略了SIGCHLD信号,
那么子进程将不会僵死,那么system将得不到子进程的退出状态。
也就是说system函数的返回值并不是子进程退出时的状态。
而2.4内核,只要父进程没有调用wait系列函数,子进程就将僵死。
不论是否忽略了SIGCHLD信号。
)
如果,我们在我们的server中需要调用system来调用外部脚本或程序来执行某写工作。
int ret = system(command);
if( ret == 0)
{
//成功
}
else
{
//失败
}
其中ret用来接收子进程退出是的返回值。即exit的返回值。
但是由于在deamon中忽略了SIGCHLD信号,所以主进程将不再接收子进程的返回值。所以,ret的值不能正确反映子进程的退出状态。
正确的做法是::
sighandler_t old_handler;
old_handler = signal(SIGCHLD,SIG_DFL); //为了准确地获取 system 函数的返回值,不能显式(SIG_IGN)地忽略 SIGCHLD 信号
system(command); //system 函数:1.fork一个进程;2.在子进程中调用 exec() 去执行新程序;3.在父进程中调用 waitpid 去等待子进程结束
signal(SIGCHLD,old_handler); //old_handler 记录了之前对于 SIGCHLD 信号的处理方式,现在还原回去
2、system相关问题::
system函数其实是调用fork,exec,waitpid来实现的。
1、fork一个进程;
2、在子进程中调用exec去执行新程序。
3、在父进程中调用waitpid去等待子进程结束。
如果在父进程已经signal(SIGCHLD,SIG_IGN);那么子进程结束时,子进程的返回值不能被waitpid接收。
这个是必须关注的问题。
原文地址:http://www.360doc.com/content/14/0305/09/13084517_357841525.shtml