我有点难以理解python是如何解决这个简单问题的。
我的问题很简单。如果你使用以下代码,它将挂起。这在子流程模块文档中有很好的记录。
import subprocess
proc = subprocess.Popen(['cat','-'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
)
for i in range(100000):
proc.stdin.write('%d\n' % i)
output = proc.communicate()[0]
print output
寻找一个解决方案(有一个很有见地的线索,但我现在已经失去了它)我发现这个解决方案(除其他外)使用了一个显式分叉:
import os
import sys
from subprocess import Popen, PIPE
def produce(to_sed):
for i in range(100000):
to_sed.write("%d\n" % i)
to_sed.flush()
#this would happen implicitly, anyway, but is here for the example
to_sed.close()
def consume(from_sed):
while 1:
res = from_sed.readline()
if not res:
sys.exit(0)
#sys.exit(proc.poll())
print 'received: ', [res]
def main():
proc = Popen(['cat','-'],stdin=PIPE,stdout=PIPE)
to_sed = proc.stdin
from_sed = proc.stdout
pid = os.fork()
if pid == 0 :
from_sed.close()
produce(to_sed)
return
else :
to_sed.close()
consume(from_sed)
if __name__ == '__main__':
main()
虽然这个解决方案在概念上非常容易理解,但它使用了一个以上的流程,并且与子流程模块相比停留在太低的级别上(这只是为了隐藏这类事情……)。
我想知道:是否有一个简单而干净的解决方案使用子流程模块,它不会挂起,或者要实现这种模式,我必须后退一步,实现一个老式的select循环或显式fork?
谢谢
如果不想将所有数据保存在内存中,则必须使用select。E、 例如:
如果您想要一个纯Python解决方案,您需要将读写器放在一个单独的线程中。
threading
包是一种轻量级的方法,可以方便地访问公共对象,并且没有混乱的分叉。看到
subprocess
模块现代化,以支持流和协程,这可能是一件好事,这将允许混合Python片段和shell片段的管道被构建得更加优雅。下面是我用来通过子进程加载6G mysql转储文件的东西。远离外壳=正确。不安全,开始浪费资源。
相关问题 更多 >
编程相关推荐