有以下代码:
child = pexpect.spawn("prog")
#some delay...
child.expect(Name .*: )
child.sendline('anonymous')
当启动子进程时,它可以开始向其stdout发送大量数据,例如日志信息。这是否意味着pexpect开始查看所有孩子的标准(从过程开始到当前时刻)?或者pexpect在expect
仅调用后才开始执行此操作?
我的子进程会生成大量日志信息。而CPU的进展非常缓慢。我认为这样的实施可能会导致
答案 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
一起使用非常有用。当关键字参数
searchwindowsize
为None
(默认值)时,将在每次接收传入数据的迭代中搜索完整缓冲区。每次迭代时扫描的默认字节数非常大 并且可以减少以附带降低搜索成本。在expect()
返回后,将显示完整的缓冲区属性 无论maxread
值是多少,都保持searchwindowsize
大小。