从标准输入读取时子进程挂起(fork / dup2竞争状况)?

时间:2018-07-30 19:46:11

标签: c++ linux pipe fork dup2

我有一个分叉以执行子进程的进程,该子进程接收来自stdin的条目并写入stdout。

简而言之,我的代码如下:

int fd[2];
int fd2[2];
if (pipe(fd) < 0 || pipe(fd2) < 0)
        throws exception;

pid_t p = fork();
if (p == 0) // child
{
        close(fd[0]); //not needed
        dup2( fd[1],STDOUT_FILENO);
        dup2( fd[1],STDERR_FILENO);
        close(fd2[1]); //not needed

        //what if  write calls on parent process execute first?
        //how to handle that situation
        dup2( fd2[0],STDIN_FILENO);
        string cmd="./childbin";

        if (execl(cmd.c_str(),(char *) NULL) == -1)
        {
                exit (-1);
        }
        exit(-1);
}
else if (p > 0) // parent
{
        close(fd[1]); //not needed
        close(fd2[0]);
        if (write(fd2[1],command.c_str(),command.size())<0)
        {
                throw exception;
        }

        close(fd2[1]);

        //waits for child to finish.
        //child process actually hangs on reading for ever from stdin.
        pidret=waitpid(p,&status,WNOHANG))==0)

.......

}

子进程保持永远等待STDIN中的数据。子进程和父进程之间是否可能存在竞争条件?我认为这可能是问题,但不是很确定,也不确定如何解决。

谢谢。

更新: 一些有用的信息。 父进程是一个守护程序,此代码每秒运行几次。它可以工作97%的时间(约3%的情况,子进程保持之前描述的状态)。

更新2 在dup2调用中添加验证后,那里没有错误,永远不会引发下一个条件。

if(dup2(...) == -1) {
     syslog(...)
}

1 个答案:

答案 0 :(得分:0)

您遗漏了wait,这就是为什么在3%的情况下,您会在孩子之前让父母做父母。请参阅底部的示例。

另外,您应该在不使用的fd上呼叫close,然后再执行其他操作。