C 用fork结束父进程,避免变成僵尸

C 用fork结束父进程,避免变成僵尸,c,linux,fork,ipc,C,Linux,Fork,Ipc,我试图在C项目中实现一些代码,以避免使用pclose阻塞我的项目。现在我使用fork+exec,但我有一个问题。我已经创建了一个管道来连接这两个进程。在子进程中,我调用exec来执行读取输入的脚本,并在父进程中捕获脚本的输出 问题是脚本会被随机阻止,我不想让它阻止我的程序。当父进程结束读取输出时,它不需要等待就完成了,以避免无限地等待,但正因为如此,子进程变成了僵尸进程 这是我的密码: int pipefd[2]; int nbytes = 0; sign

我试图在C项目中实现一些代码,以避免使用pclose阻塞我的项目。现在我使用fork+exec,但我有一个问题。我已经创建了一个管道来连接这两个进程。在子进程中,我调用exec来执行读取输入的脚本,并在父进程中捕获脚本的输出

问题是脚本会被随机阻止,我不想让它阻止我的程序。当父进程结束读取输出时,它不需要等待就完成了,以避免无限地等待,但正因为如此,子进程变成了僵尸进程

这是我的密码:

int    pipefd[2];
        int nbytes = 0;

        signal(SIGCHLD, kill_child);

        pipe(pipefd);
        if (vfork() == 0)
        {
                close(pipefd[0]);
                dup2(pipefd[1], 1);
                close(pipefd[1]);
                execl("/bin/sh", "sh", "-c", cpCommand, NULL);
                exit(EXIT_SUCCESS);
        }
        else
        {
                close(pipefd[1]);
                while ((nbytes = read(pipefd[0], output, sizeof(output))) > 0)
                {
                        write(1, output, nbytes);
                }
                close(pipefd[1]);
        }
        strcpy(cpOutput, output);


void kill_child(int sig_num)
{
        wait();
}
解决这个问题的最佳方法是什么?

您可以使用双叉:

 pid_t pid = fork();
 if (pid == 0) {
      pid = fork();
      if (pid == 0) {
           ...
           execl(...);
      }
      _exit(0);
 }

 waitpid(pid, ...);

 read(...);
也许,应该在子级中调用setsid和/或忽略SIGHUP

上面的代码将EXCL从主程序中分离出第二个子程序,init将获得它


您可能需要使用一些控制管道来向主进程发送错误信号EXCEL失败。

您的意思是在父块中进行读取调用吗?然后使管道不堵塞。或者你的意思是等待呼叫阻塞?然后使用带有WNOHANG标志的waitpid。所有进程在某个时候都会变成僵尸。如果父进程超过子进程,则子进程将处于僵死状态,直到发出显式等待调用。如果父进程终止,而子进程仍在孤立进程上运行,则它将被init进程采用。内核将在最坏的情况下杀死所有子进程:当您重新启动/关闭系统时,init偶尔会收获僵尸进程,现在我想在父进程中使用waitpid进行轮询,如果子进程没有完成,则在超时后杀死子进程。我认为我与execl有问题,因为我在它之后放置了printf,它从未显示,但脚本结束。exec*函数族的成员仅在参数执行失败时返回,否则它们不会返回,因此放在它们后面的任何语句都不会执行。详见《男人3执行官》。@选民:如果你能为自己的行为辩护,那就太好了