子进程等待按键输入时匿名管道无数据返回问题咨询
问题根因
- 父进程没有转发终端输入到子进程的输入管道
你重定向了子进程的标准输入绑定到stdout_pipe[0],这个管道的写端stdout_pipe[1]握在父进程手里,但现有父进程逻辑只做了读取子进程的输出,完全没有读取当前终端的输入,也没有把输入内容写到stdout_pipe[1]传给子进程。你在终端敲的按键只会传到父进程的标准输入,父进程不处理转发,子进程当然收不到任何输入,system调用的read命令就会一直阻塞。 - 管道重定向后的输出缓冲问题
当标准输出被重定向到管道时,默认缓冲模式会从行缓冲变为全缓冲,如果没有主动刷缓冲,子进程printf的内容可能会卡在缓冲区里,父进程暂时读不到,建议子进程每次printf后加fflush(stdout)。 - 轮询逻辑性能缺陷
用ioctl(FIONREAD)循环10000次的轮询方式会占满CPU,而且没有同步机制,极端情况会丢数据,建议用select/epoll同时监听父进程的终端输入、子进程输出管道两个文件描述符,有事件触发再处理。
修复建议
- 修改父进程逻辑,增加读取终端输入的处理:当父进程的标准输入(
STDIN_FILENO)有数据时,读取内容后直接写入stdout_pipe[1],转发给子进程即可触发read命令继续执行。 - 子进程每次打印后调用
fflush(stdout)刷出缓冲区内容,确保父进程能及时收到输出。 - 测试阶段可以先去掉管道的非阻塞标识,避免处理
EAGAIN错误增加调试复杂度,稳定后再按需开启非阻塞模式。
内容的提问来源于stack exchange,提问作者Q88Q
相关产品推荐
相关产品推荐

