2013-02-17 123 views
1

perl中的包装我需要python中的非阻塞子流程(有各种类型的shell io)。另外我对shell的输出和返回值感兴趣。有时候返回值是0,但代码实际上并没有做任何事情。
因此,我现在可以使用subprocess.call()(非阻塞但不是shell输出)或subprocess.Popen()(阻塞但shell输出)。python中的非阻塞子流程

我做了一些阅读,但唯一的解决方案看起来像有一个单独的队列来做到这一点。更容易我错过了?

回答

4

subprocess.Popen不是固有的阻塞。您仍然可以使用proc.stdin.write()proc.stdout.read();唯一的问题是,如果管道填满了,你可能会在一侧发生堵塞,甚至发生死锁[1]。如果您知道您的子进程只会读取或写入少量数据,则不必担心。

所以,你可以这样做:

proc = subprocess.Popen(['perl', 'somescript.pl'], stdout=subprocess.PIPE) 
buf = StringIO() 
CHUNKSIZE = 1024 # how much to read at a time 

while True: 
    # do whatever other time-consuming work you want here, including monitoring 
    # other processes... 


    # this keeps the pipe from filling up 
    buf.write(proc.stdout.read(CHUNKSIZE)) 

    proc.poll() 
    if proc.returncode is not None: 
     # process has finished running 
     buf.write(proc.stdout.read()) 
     print "return code is", proc.returncode 
     print "output is", buf.getvalue() 

     break 

在一个更大的应用程序,你可以安排这个在你的事件循环,电抗器等发生


[1] OS只能将就允许这么多的数据一次适合管道。假设你运行cat作为你的子进程,并向其stdin写入大量数据。 cat会将这些数据写入它自己的stdout直到它填满,然后它会阻塞,直到你的程序从标准输出中读取一些数据并清空管道。但是你的程序仍然写入stdin,并且cat不再读取它,所以管道也会填满。这两个进程都会阻塞写入,等待另一个进行读取,这将永远不会发生。

+0

谢谢,我试试看。不应该是很多数据 – user501743 2013-03-01 22:08:19