在线文档教程

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对象

Popen3Popen4类的实例具有以下方法:

Popen3.poll()

-1如果子进程尚未完成,则返回,否则返回状态码(请参阅wait())。

Popen3.wait()

等待并返回子进程的状态码。状态码对进程的返回码和有关它是使用exit()系统调用退出还是因信号而死亡的信息进行编码。帮助解释状态码的功能在os模块中定义; 请参阅W*()功能族的过程管理部分。

以下属性也可用:

Popen3.fromchild

提供子进程输出的文件对象。对于Popen4情况下,这将同时提供标准输出和标准错误流。

Popen3.tochild

为子进程提供输入的文件对象。

Popen3.childerr

如果capturestderr对构造函数为true ,则提供来自子进程的错误输出的文件对象,否则None。这将始终是NonePopen4实例。

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*类所提供的每个单独文件。