孩子退出后,waitpid没有回来

时间:2016-05-07 13:30:08

标签: c wait

使用相当标准的fork进程:

int   pipe_to_child[2];
int   pipe_from_child[2];
int   child_exit_status = -1;

pid_t child_pid = fork();
if (child_pid == 0) {
    close(pipe_from_child[0]); // close their read end
    close(pipe_to_child[1]); // Close their write end
    dup2(pipe_to_child[0], STDIN_FILENO); // Tie the in pipe to stdin
    dup2(pipe_from_child[1], STDOUT_FILENO); // Tie stdout to the out pipe
    // Run the child process
    execve(file_to_run, argv_for_prog, env_for_prog);
}
else {
    close(pipe_from_child[1]); // close their write end
    close(pipe_to_child[0]); // Close their read end
    if (input_to_prog != NULL) write(pipe_to_child[1], input_to_prog, strlen(input_to_prog)); // Send the stdin stuff
    close(pipe_to_child[1]); // Done so send EOF

    // Wait for the child to end
    waitpid(child_pid, &child_exit_status, 0);

    // Do post end-of-child stuff
}

这通常可以按预期工作。

但是,当子进程(shell脚本)在后台设置进一步的进程时。即使子进程退出(并且不再由ps列出),waitpid也不会返回。

这个脚本就是为了启动在后台运行的inadyn-mt(一个DDNS更新程序)。

#!/bin/sh
inadyn-mt --background

(如果我放入& after inadyn-mt后没有区别)

1 个答案:

答案 0 :(得分:0)

事实证明,问题是管道没有关闭。虽然子进程退出正常,因为它产生了一个进一步的进程,这个进程(即使它不需要它们)与子进程stdin和stdout的管道绑定。我使用的解决方案是在我要从孩子身上剥离孩子时不要设置管道。