我有一个这样的代码...
c = fork();
if(c==0) {
close(fd[READ]);
if (dup2(fd[WRITE],STDOUT_FILENO) != -1)
execlp("ssh", "ssh", host, "ls" , NULL);
_exit(1);
}
close(fd[WRITE]);
fdREAD和fdWRITE是管道文件描述符。
当我连续运行它时,当我使用ps ax时,有很多僵尸进程。如何纠正这一点?这是因为我没有使用父进程来等待子进程的退出状态...
发布于 2011-02-02 10:19:53
如果您不打算对子进程执行wait
,请将SIGCHLD
处理程序设置为SIG_IGN
,让内核自动获取您的子进程,例如。
signal(SIGCHLD, SIG_IGN);
发布于 2011-02-02 10:13:25
是,上级必须等待下级退货状态。您可以通过在父进程中捕获SIGCHILD
,然后在capture方法中调用waitpid
来异步完成此操作。
发布于 2013-08-07 09:49:50
是的,应该从父级调用waitpid()。waitpid()将清理当前处于终止状态的父进程的所有子进程。
您可以将以下代码添加到您的程序中:
if(c>0)
{
while(1){
ret = waitpid(-1,&status,0);
if(ret>0){
if(WIFEXITED(status)){
if(WEXITSTATUS(status) == 0){
printf("child process terminated normally and successfully\n");
}
else{
printf("child process terminated normally and unsuccessfully\n");
}
}
else{
printf("child process terminated abnormally and unsuccessfully\n");
}
}
if(ret<0) {
break;
}
}
}
仅供参考:更多关于waitpid的信息。
第一个参数被设置为-1,这样waitpid()将清理这个父进程的所有子进程,这是当前在终止的state.The第一个参数也可以是+ve -在这种情况下,waitpid()将只清理特定的子process.Most通常用于将第一个参数设置为-1也可以参考手册页的waitpid()。第二个参数用于提取子进程的终止/退出状态代码- waitpid()系统调用API在调用系统调用API时填充状态字段。最后一个字段是标志字段-当前未使用-在大多数情况下,标志字段将设置为0-表示系统调用API的默认行为!如果您确实需要使用标志,请参考waitpid()手册页面。
注意:在您提交的代码中,当execlp()失败时,将调用_exit(1)。因此,您可以为execlp()设置一个失败条件,且可以调用条件_exit()。原因是,execlp()函数只在发生错误时返回。
修改后的代码可能如下所示:
c = fork();
if(c==0) {
close(fd[READ]);
if (dup2(fd[WRITE],STDOUT_FILENO) != -1)
ret_execlp = execlp("ssh", "ssh", host, "ls" , NULL);
if(ret_execlp == -1 ) {
printf("execlp is failed");
_exit(1);
}
}
close(fd[WRITE]);
我很欣赏上面两个答案。希望这个答案能让你更加清晰。谢谢。
https://stackoverflow.com/questions/4873092
复制