我有兴趣编写独立的程序模块,这些程序模块作为独立的线程运行,我可以用管道挂钩。我的动机是我可以完全独立地编写和测试每个模块,甚至可以用不同的语言编写它们,或者在不同的机器上运行不同的模块。这里有各种各样的可能性。我已经使用了一段时间的管道,但我不熟悉它的行为的细微差别。
答案 0 :(得分:4)
似乎接收端会 阻止等待输入,我会 预期
您希望正确的“读取”调用将会阻塞,直到出现某些内容。但是,我相信有一些C函数可以让你“窥视”在管道中等待的数量(以及多少)。不幸的是,我不记得这是否会阻止。
发送端有时会阻塞 等待某人从中读 流
不,发送不应该阻止。如果这是跨越网络到另一台计算机的管道,请考虑这些后果。您是否希望等待(通过可能的高延迟)让另一台计算机响应它收到它?现在,如果目的地的阅读器句柄已关闭,则这是一种不同的情况。在这种情况下,您应该进行一些错误检查以处理它。
如果我在流中写了一个eof,我可以 继续写入该流 直到我关闭它
我认为这取决于您使用的语言及其管道的实现。在C中,我会说不。在linux shell中,我会说是的。其他有更多经验的人则必须回答这个问题。
行为有差异吗? 命名和未命名的管道? 据我所知,是的。但是,我对named vs unnamed没有多少经验。我相信不同之处是:
管道I的哪一端是否重要 首先打开命名管道?
通常不会,但是在尝试创建和链接线程的初始化时可能会遇到问题。您需要有一个主线程来创建所有子线程并相互同步它们各自的管道。
管道的行为是否一致 不同的Linux系统之间?
同样,这取决于使用什么语言,但通常是肯定的。有没有听说过POSIX?这是标准(至少对于Linux,Windows自己做的事情)。
管道的行为是否依赖 我正在使用的外壳或我的方式 配置了吗?
这是一个灰色地带。答案应该不是因为shell本质上应该进行系统调用。但是,到那时为止的所有事情都可以争夺。
我还有其他问题吗? 请问
您提出的问题表明您对系统有一个很好的理解。继续研究并专注于你将要处理的水平(shell,C等)。通过尝试,你会学到很多东西。
答案 1 :(得分:4)
这完全基于类UNIX系统;我不熟悉最新版Windows的具体行为。
看起来接收端会阻止等待输入,这是我期望的,但是发送端阻塞有时会等待某人从流中读取吗?
是的,虽然在现代机器上它可能不会经常发生。管道有一个可能可能填满的中间缓冲区。如果是这样,管道的写入侧确实会阻塞。但是如果你考虑一下,就没有很多文件可以冒这个风险。
如果我在流中写了一个eof,我可以继续写入该流,直到我关闭它吗?
嗯,你的意思是像CTRL-D,0x04?当然,只要流设置那样。即506 # cat | od -c
abc
^D
efg
0000000 a b c \n 004 \n e f g \n
0000012
命名和未命名管道的行为是否存在差异?
是的,但它们是微妙的,并且依赖于实现。最大的一个是你可以在另一端运行之前写入命名管道;使用未命名的管道,文件描述符在fork / exec进程期间共享,因此在没有进程的情况下无法访问临时缓冲区。
使用命名管道首先打开管道的哪一端?
不。
管道的行为是否在不同的Linux系统之间保持一致?
在合理范围内,是的。缓冲区大小等可能会有所不同。
管道的行为是否依赖于我正在使用的shell或我配置它的方式?
没有。当你创建一个管道时,在你的父进程(shell)创建一个具有一对文件描述符的管道,然后做一个像这个伪代码的fork exec:
<强>父强>:
create pipe, returning two file descriptors, call them fd[0] and fd[1]
fork write-side process
fork read-side process
<强>写侧强>:
close fd[0]
connect fd[1] to stdout
exec writer program
<强>阅读侧强>:
close fd[1]
connect fd[0] to stdin
exec reader program
如果我想以这种方式使用烟斗,我应该问的其他问题或者我应该注意的问题吗?
你想要做的一切真的要像这样排成一行吗?如果没有,您可能想要考虑更通用的架构。但是,通过管道的“窄”界面进行交互的大量独立过程的观点是可取的。
[更新:我首先反转了文件描述符索引。他们现在是正确的,请参阅man 2 pipe
。]
答案 2 :(得分:4)