2011-07-11 103 views
7

我有一个像下面这样的结构:链POPEN子进程正常

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

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

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

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

  1. /dev/stdoutcap是从OS的实际标准输出谈论不同?也就是说,在输入管道-enc中,即使其他进程正在与OS上的/ dev/stdout聊天,我是否还会在这两个进程之间获得干净的数据通道?
  2. 在阻塞/排队行为方面会有什么显着差异吗?我认为在我的第一个例子中,命名管道将是一个缓冲的4096字节,并且如果cap/enc不够快写入/读取,将在任一端阻塞,但如果我错了,请纠正我。
  3. 是需要产卵或终止的任何特殊顺序,还是我应该知道的任何其他陷阱?

回答

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