c - 父子进程之间的管道问题
问题描述
使用管道,父亲从标准输入读取并使用管道将其发送到子进程,以便子进程可以对输入执行 wordcount。打开和关闭管道 p[0] 和 p[1] 的问题。为什么我不能 dup2(p[1],1) 然后 write(1,buffer,1)?仅当我在没有 dup2(p[1],1) 的情况下执行 write(p[1],buffer,1) 时才有效。
int main(int argc, char **argv){
int p[2];
int n;
char buffer[1024];
pipe(p);
if(!fork()){
close(p[1]);
dup2(p[0],0);
close(p[0]);
execlp("wc","wc",NULL);
_exit(0);
}
else{
close(p[0]);
dup2(p[1],1);
while((n=read(0,buffer,1))>0){
write(1,buffer,1);
}
close(p[1]);
wait(NULL);
}
return 0;
}
解决方案
为什么我不能 dup2(p[1],1) 然后 write(1,buffer,1)?
你可以,虽然它看起来毫无意义。但是,如果您尝试使用(仅)写入标准输出的 I/O 函数之一,这将更有意义。
仅当我在没有 dup2(p[1],1) 的情况下执行 write(p[1],buffer,1) 时才有效。
这取决于您所说的“作品”是什么意思。当我运行您的原始代码时,程序从不打印任何输出并且从不终止,但这并不意味着父级的写入没有成功地将数据发送给子级。
问题是孩子不知道何时到达输入的末尾。它正在等待其输入端的文件结束信号,只要有任何打开的文件描述符与管道的写端相关联,它就不会出现。
如果父级没有欺骗管道的写端,那么它只打开了一个文件描述符,而子级有一个。两者都在适当的时候关闭它们。但是在您提供的代码中,父级p[1]
复制到文件描述符 1,因此它有两个打开的文件描述符指向管道端。它只会关闭p[1]
,使文件描述符 1 保持打开状态,因此子进程一直在等待更多输入。
如果 FD 1 退出,父级将关闭它,允许子级完成,但它正在等待子级先终止。这是与 I/O 重定向相关的更常见的死锁错误之一。我建议不要让父级复制文件描述符,因为复制到 FD 1 会不必要地阻止它将其标准输出用于任何其他目的。但是如果它确实欺骗了它,那么它必须在子进程终止之前关闭两个文件描述符。
推荐阅读
- c# - ASP.NET Core API 版本控制 - 部分取代以前的方法版本
- java - 道房数据库无法访问
- python - 调试为什么 Dask Dataframe 操作什么都不做
- c# - 格式化字符串(掩码?)
- java - Java中的Euler项目#3;程序不输出结果
- ansible - Ansible 变量值作为变量名
- python - dp 解决方案如何涵盖所有子数组和?
- reactjs - React Data Grid 在 src/DataGrid.tsx:268 处失败,抛出:TypeError: rows is undefined
- android - Android:如何动态地将按钮添加到 GridView?
- javascript - Safari createMediaElementSource 在 HLS/m3u8 视频源上是否损坏?