正确地链接Popen子过程

时间:2011-07-11 07:23:15

标签: python subprocess pipe named-pipes popen

我有如下构造:

os.mkfifo('pipe.tmp')
enc = Popen(['encoder', '-i', 'pipe.tmp'])
cap = Popen(['capture', '-f', 'pipe.tmp'])

此处cap是一个通常写入文件(由-f指定)的过程,但我可以通过提供/dev/stdout作为输出文件将数据写入屏幕。类似地,enc期望从类似文件的对象中读取,并且我能够通过提供-作为输入来从管道读取它。所以不是在os中使用命名管道,我认为特殊文件可能没有必要,我可以使用这样的未命名管道..

cap = Popen(['capture', '-f', '/dev/stdout'], stdout=PIPE)
enc = Popen(['encoder', '-i', '-'], stdin=cap.stdout)
cap.stdout.close()

(注意产卵顺序的逆转)。我更喜欢这个,因为临时文件似乎没必要,但我有点担心这个构造是否会以我期望的方式链接进程。

  1. /dev/stdout正在谈论的cap与操作系统中的实际标准输出不同?也就是说,使用-中的输入管道enc,我会在这两个进程之间获得一个干净的数据通道,即使其他进程正在与OS上的/ dev / stdout聊天吗?
  2. 阻止/排队的行为会有什么显着差异吗?我想在我的第一个例子中,命名管道将是一个缓冲的4096字节,并且如果cap / enc没有足够快地写入/读取,将在任一端阻塞,但如果我是正确的话,请纠正我错误。
  3. 是否需要产卵或终止的特殊订单,或者我应该注意的任何其他问题?

1 个答案:

答案 0 :(得分:1)

  1. / dev / stdout为您提供当前进程的标准输出,因此您应该可以使用它。 (没有关于/ dev / stdout的任何'全局')
  2. 第一个示例中fifo的大小取决于系统的配置(我不确定如何更改)。但是subprocess.Popen允许您为其I / O操作定义缓冲区大小,因此您应该能够调整它。 更新:稍微研究一下,我发现不受bufsize参数影响的管道有64kB的限制。不知道怎么解决这个问题(除了更频繁地阅读并手动处理缓冲)
  3. 对于您的第二个示例,看起来您需要按照您给出的顺序启动,因为您需要在启动enc之前使用cap.stdout。或者,您可以将两个进程断开连接并手动处理它们之间的通信。