popen2
popen2 — Subprocesses with accessible I/O streams
自2.6版弃用:此模块已过时。使用该subprocess
模块。特别检查用子流程模块部分替换旧功能。
这个模块允许你产生进程并连接到它们的输入/输出/错误管道,并在Unix和Windows下获得它们的返回代码。
该subprocess
模块提供了更强大的功能,用于产生新过程并检索其结果。使用subprocess
模块比使用模块更可取popen2
。
这个模块提供的主要接口是三个工厂功能。对于其中的每一个,如果指定了bufsize
,它将指定I / O管道的缓冲区大小。模式
,如果提供,应该是字符串'b'
或't'
; 在Windows上,需要确定文件对象是否应以二进制或文本模式
打开。模式
的默认值是't'
。
在Unix上,cmd
可能是一个序列,在这种情况下,参数将直接传递给程序,而无需shell干预(如同os.spawnv()
)。如果cmd
是一个字符串,它将被传递给shell(与之一样os.system()
)。
检索子进程的返回码的唯一方法是使用poll()
or 和classes wait()
上的方法; 这些只在Unix上可用。在模块中使用,和功能或等效功能时,此信息不可用。(请注意,模块函数返回的元组与模块返回的元组顺序不同。)Popen3Popen4popen2()popen3()popen4()osospopen2
popen2.popen2(cmd[, bufsize[, mode]])
执行cmd
作为子进程。返回文件对象(child_stdout, child_stdin)
。
popen2.popen3(cmd[, bufsize[, mode]])
执行cmd
作为子进程。返回文件对象(child_stdout, child_stdin, child_stderr)
。
popen2.popen4(cmd[, bufsize[, mode]])
执行cmd
作为子进程。返回文件对象(child_stdout_and_stderr, child_stdin)
。
2.0版本中的新功能。
在Unix上,定义由工厂函数返回的对象的类也是可用的。这些不用于Windows实现,并且不适用于该平台。
class popen2.Popen3(cmd[, capturestderr[, bufsize]])
这个类代表一个子进程。通常情况下,Popen3
实例使用所创建的popen2()
和popen3()
上述库功能。
如果不使用其中一个辅助函数创建Popen3
对象,则参数cmd
是在子进程中执行的shell命令。该capturestderr
标志,如果为true,指定对象应该捕获子进程的标准错误输出。默认值是false。如果指定了bufsize
参数,它将指定子进程的I / O缓冲区的大小。
class popen2.Popen4(cmd[, bufsize])
与Popen3
标准输出相似,但始终将标准错误捕获到同一个文件对象中。这些通常是使用创建的popen4()
。
2.0版本中的新功能。
1. Popen3和Popen4对象
类Popen3
和Popen4
类的实例具有以下方法:
Popen3.poll()
-1
如果子进程尚未完成,则返回,否则返回状态码(请参阅wait()
)。
Popen3.wait()
等待并返回子进程的状态码。状态码对进程的返回码和有关它是使用exit()
系统调用退出还是因信号而死亡的信息进行编码。帮助解释状态码的功能在os
模块中定义; 请参阅W*()
功能族的过程管理部分。
以下属性也可用:
Popen3.fromchild
提供子进程输出的文件对象。对于Popen4
情况下,这将同时提供标准输出和标准错误流。
Popen3.tochild
为子进程提供输入的文件对象。
Popen3.childerr
如果capturestderr
对构造函数为true ,则提供来自子进程的错误输出的文件对象,否则None
。这将始终是None
为Popen4
实例。
Popen3.pid
子进程的进程ID。
2.流量控制问题
无论何时您正在进行任何形式的进程间通信,都需要仔细考虑控制流程。这个模块(或os
模块等价物)提供的文件对象仍然是这种情况。
当从父进程读取子进程的标准输出时,读取从标准错误写入大量数据的子进程的输出时,可能会发生死锁。读取和写入的其他组合可能会出现类似的情况。基本因素是,_PC_PIPE_BUF
一个进程以阻塞的方式正在写入多于一个字节,而另一个进程正在从第一个进程读取,也是以阻塞的方式进行读取。
有几种方法可以处理这种情况。
在很多情况下,最简单的应用程序更改将在父进程中遵循此模型:
import popen2
r, w, e = popen2.popen3('python slave.py')
e.readlines()
r.readlines()
r.close()
e.close()
w.close()
在子类中使用这样的代码:
import os
import sys
# note that each of these print statements
# writes a single long string
print >>sys.stderr, 400 * 'this is a test\n'
os.close(sys.stderr.fileno())
print >>sys.stdout, 400 * 'this is another test\n'
尤其要注意,sys.stderr
必须在写入所有数据后关闭,否则readlines()
不会返回。还要注意os.close()
必须使用,因为sys.stderr.close()
不会关闭stderr
(否则分配sys.stderr
将默默关闭它,因此不会打印更多错误)。
需要支持更一般的方法的应用程序应该将I / O与管道上的I / O及其select()
循环集成在一起,或者使用单独的线程来读取由使用哪个popen*()
功能或Popen*
类所提供的每个单独文件。