【问题标题】:child process hanging while reading from stdin (fork/dup2 race condition)?从标准输入读取时子进程挂起(fork/dup2 竞争条件)?
【发布时间】:2019-01-07 03:13:39
【问题描述】:

我有一个为了执行子进程而分叉的进程,该子进程接收来自标准输入的条目并写入标准输出。

我的代码简写如下:

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(...)
}

【问题讨论】:

  • dup2 3% 失败案例的返回值/errno 是多少?
  • @Surt 实际上,我意识到我没有处理来自 dup2 的返回。我将更新代码并进行测试。谢谢!
  • 也许我遗漏了一些东西,但是为什么你需要为父->子通信创建一个管道?您不能按原样使用 STDOUT/STDIN 吗?还有多少写在管道上?如果您的孩子超过PIPE_BUF 写入,它将阻止等待管道被清空,但您的父母已经在waitpid() 上被阻止 - 可能不是这里的问题,但以后可能会引起关注。

标签: c++ linux pipe fork dup2


【解决方案1】:

您缺少wait,这就是为什么您在 3% 的情况下先运行父级,然后运行子级。请参阅底部的示例。

此外,在做其他任何事情之前,您应该在不使用的 fd 上调用 close

【讨论】:

  • 嗨,“错过等待”是什么意思?
  • @ArturoGarcia 查看链接以获取解释。
  • 哪一个?您答案中的唯一链接指向等待的手册页。我知道什么是等待。你能说得更具体点吗?
  • 嗯昨天我很清楚线程的执行顺序可能会影响结果,但现在我怀疑等待是正确的:(
猜你喜欢
  • 2019-10-17
  • 1970-01-01
  • 2016-07-26
  • 1970-01-01
  • 2017-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多