subprogress 监控子进程的输出
import subprocess
import psutil
import time
import select
from concurrent.futures import ThreadPoolExecutor
def main():
p = subprocess.Popen(["python", "test2.py"], stdout=subprocess.PIPE,text=True, stderr=subprocess.PIPE)
# stdout, stderror = p.communicate() #会阻塞,但不用担心管道被阻塞
stdout = ""
stderr = ""
memory_usage = 0
p1 = psutil.Process(p.pid)
while p.poll() is None:
memory_usage = max(p1.memory_info().rss /1024 / 1024,memory_usage)
stdout = stdout + p.stdout.read()
# Wait for up to 20ms for output
reads = select.select([p.stderr.fileno()], [], [], 0.02)[0]
# If there is output
if reads:
# Read a line from stderr
stderr = stderr + p.stderr.readline()
else:
# If there was no output after 20ms, do something else (like sleeping for a bit)
time.sleep(0.02)
print(stderr)
print(memory_usage)
print(stdout[:30])
if __name__ == "__main__":
main()
import time
import logging
for i in range(1,10):
print(i)
for i in range(3000):
print("2222222222222222222222")
time.sleep(1)
select.select() 是一个Python中的函数,它允许程序监视多个文件描述符,等待它们变得可读、可写或者有错误发生。这个函数通常用于实现多路复用I/O,即同时处理多个连接或者文件。
select.select() 函数有四个参数:
第一个参数是一个列表,包含了你想要监视的文件描述符,等待它们变得可读。
第二个参数也是一个列表,包含了你想要监视的文件描述符,等待它们变得可写。
第三个参数也是一个列表,包含了你想要监视的文件描述符,等待它们有错误发生。
第四个参数是一个超时时间,单位是秒。如果在这个时间内没有任何文件描述符变得可读、可写或者有错误发生,函数就会返回。
在你的代码中,select.select([p.stderr.fileno()], [], [], 0.02)[0] 这行代码的意思是:
[p.stderr.fileno()] 是你想要监视的文件描述符列表,你只关心 p.stderr 是否有数据可以读。fileno() 方法返回的是文件描述符的整数值。
第二个和第三个参数都是空列表,表示你不关心任何文件描述符是否变得可写或者有错误发生。
0.02 是超时时间,单位是秒。如果在20毫秒内 p.stderr 没有数据可以读,select.select() 就会返回。
select.select() 返回的是三个列表,分别对应于输入的三个列表。每个列表中的元素都是在超时时间内变得可读、可写或者有错误发生的文件描述符。在你的代码中,你只关心第一个列表,所以用 [0] 取出了这个列表。
所以,reads = select.select([p.stderr.fileno()], [], [], 0.02)[0] 这行代码的意思是:等待最多20毫秒,看 p.stderr 是否有数据可以读,如果有,就把 p.stderr 的文件描述符放入 reads 列表中。