pexpect如何分析孩子的stdout?

时间:2016-12-26 12:59:12

标签: python-3.x pexpect

有以下代码:

child = pexpect.spawn("prog")
#some delay...
child.expect(Name .*: )
child.sendline('anonymous')

当启动子进程时,它可以开始向其stdout发送大量数据,例如日志信息。这是否意味着pexpect开始查看所有孩子的标准(从过程开始到当前时刻)?或者pexpect在expect仅调用后才开始执行此操作?

我的子进程会生成大量日志信息。而CPU的进展非常缓慢。我认为这样的实施可能会导致

1 个答案:

答案 0 :(得分:1)

在生成子进程后,子进程将write()其数据发送到pty(从属端)并等待父进行read()来自pty(主方)的数据。如果没有child.expect()孩子的write()在输出过多数据时可能被阻止,因为写缓冲区已满。

child.expect()与模式匹配时,它将返回,然后您必须再次调用child.expect(),否则在输出太多数据后,儿童可能仍会被阻止。

参见以下示例:

# python
>>> import pexpect
>>> ch = pexpect.spawn('find /')
>>> ch
<pexpect.pty_spawn.spawn object at 0x7f47390bae90>
>>>

此时产生了find并且它已经输出了一些数据。但是我没有调用ch.expect()所以find现在被阻止(休眠)并且它不消耗CPU。

# ps -C find u
USER     PID %CPU %MEM  VSZ   RSS TTY     STAT START   TIME COMMAND
root  100831  0.0  0.2 9188  2348 pts/12  Ss+  10:23   0:00 /usr/bin/find /
# strace -p 100831
Process 100831 attached
write(1, "\n", 1             <-- The write() is being blocked

此处,STAT S表示正在休眠s表示会话负责人+表示正在处理< / em>的)。

根据pexpect的文档,spawn()的两个选项可能会影响性能:

  

maxread属性设置读取缓冲区大小。这是Pexpect将尝试的最大字节数   一次从TTY读取。将maxread大小设置为1将关闭缓冲。 设置maxread   在从孩子那里读回大量输出的情况下,更高的值可能有助于提高性能。   此功能与searchwindowsize一起使用非常有用。

     

当关键字参数searchwindowsizeNone(默认值)时,将在每次接收传入数据的迭代中搜索完整缓冲区。每次迭代时扫描的默认字节数非常大   并且可以减少以附带降低搜索成本。在expect()返回后,将显示完整的缓冲区属性   无论maxread值是多少,都保持searchwindowsize大小。