gpt4 book ai didi

c - 与dup2(),exec()和管道混淆

转载 作者:太空宇宙 更新时间:2023-11-04 02:43:14 24 4
gpt4 key购买 nike

我一直在努力理解命令dup2()exec()和管道的概念。
我要达到的目标是:
将程序X的输出通过管道传送到程序Y的输入。
一些基本的东西,比如who | sort
有一个父级和两个子级,其中子级负责执行程序,父级将程序传递给子级。
以下是我对管道的一些不理解:
P1)管道被视为文件,应该是单向的,但是什么阻止了我将一个管道用于多个单向通信信道?
所以,假设我有pipe1和三个进程(P-父进程-C1C2,子进程),它们通过分叉打开管道。所有这些进程都使用文件描述符。
假设我们做的一切都是正确的,关闭未使用的管端,P现在会向C1写入一些内容。再次使用管道在C1C2之间进行通信有什么问题?
就在写这个问题的时候,我突然想到一个想法:当许多进程可能同时打开它(两个进程正在阻塞以获取读取)时,谁从中读取数据,即系统不能确定谁想读取写入其中的缓冲数据,这是否有问题?如果是,这是如何在系统中实现的?
我真的试着去理解这个概念,所以请容忍我。
要将这个问题应用到现实生活中,我要处理的是一些伪代码:
P:
P关闭不需要的读取结束
pipe1通过PC1发送程序参数('who')
pipe1关闭写入端
等待孩子们离开
C1类:
PP的读取端读取参数
C1 pipe1s标准输出到 C1
dup2()关闭 pipe1的两端(因为我们已经欺骗了它)
C1 pipe1s程序(“谁”)
指挥2:
C1 execvp()s从 C2读取到 dup2()的结尾,以便获取将要执行的程序的输入
pipe1关闭 stdin的两端
C2pipe1ed C2中的 stdin上等待输入
有此输入的 C1 dups程序('sort')
现在,如果我按上面描述的那样做,我就没有运气了。
但是,如果我引入另一个管道,它看起来像这样:
P:
pipe1关闭不需要的管道的两端 C2
execvp()关闭不需要的读取结束
pipe2通过 Ppipe2发送程序参数('who')
P关闭写入端
等待孩子们离开
C1类:
pipe1关闭读取结束
PC1的读取端读取参数
pipe1 Ps标准输出到 P
C1关闭 pipe2的写入端
C1关闭 pipe1的两端--此子项中有多余的
C1 dup2()s程序(“谁”)
指挥2:
pipe2 C1s读取结束 pipe2C1
pipe1关闭 pipe2的两端
pipe1C1ed execvp()中的 C2上等待输入
dup2()使用此输入执行程序
假设管道不应在多个进程中重用,因为系统可能不确定“为谁服务”,这一假设是否正确?或者有其他原因吗?

最佳答案

管道主要是为一对一的交流设计的——一个作者,一个读者。虽然没有什么可以阻止拥有尽可能多的读者和作者,但这种行为通常会使这一点变得不太有用,特别是对于多个读者:
从管道读取数据是一种破坏性操作:通过管道发送的每个字节都将被其中一个读卡器读取,无论谁先获取它。如果要广播某些信息,则需要使用不同的IPC机制或显式复制数据(如tee命令)。
如果有多个作家,他们的作品会以某种不可预知的方式穿插在一起。唯一的保证是大小小于或等于cc的写操作是原子的。
如果写入程序的数量降至零,则读取器将看到文件结束条件。
在您描述的体系结构中,有两个独立的通信通道:P向C1发送PIPE_BUF命令,C1向C2发送运行who命令的输出。在shell脚本中,这类似于

echo who | { read command; exec command; } | sort

在原始进程而不是子shell中执行 who
你的第一个建议不起作用,因为没有办法说P的输出会转到C1,C1的输出会转到C2。它仍然是相同的管道,所以P的输出可以返回到C2,C1的输出可以返回到自身,也可以是一个混合物。

关于c - 与dup2(),exec()和管道混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29858707/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com