正确地链接Popen子过程

wim*_*wim 7 python subprocess pipe popen named-pipes

我有一个像下面这样的结构:

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

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

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

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

  1. /dev/stdoutcap是从OS的实际标准输出谈论不同?也就是说,与输入管-enc我会得到这两个过程之间的数据,即使其他进程正在逢到到/ dev的/清洁的信道标准输出在OS上?
  2. 阻塞/排队行为会有什么显着差异吗?我想在我的第一个例子中,命名管道将是一个缓冲的4096字节,并且如果cap/ enc不能快速写入/读取,将在任一端阻塞,但如果我错了,请纠正我.
  3. 是否需要产卵或终止的特殊订单,或者我应该注意的任何其他问题?

Luk*_*uke 1

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