如何用Python subprocess捕获stdout同时测量子进程最大内存并设置超时?
在Python中同时捕获子进程stdout、监控最大内存并设置超时的方法
一、快速实现输出捕获与超时控制
用subprocess.run可以直接完成stdout捕获和超时设置,代码简洁直观:
import subprocess try: result = subprocess.run( ["your_command", "arg1", "arg2"], capture_output=True, text=True, timeout=100 # 超时时间,单位:秒 ) # 获取捕获的标准输出 output_content = result.stdout except subprocess.TimeoutExpired: print("子进程执行超时")
capture_output=True:同时捕获stdout和stderr;text=True:将输出转为字符串(默认是字节流格式);timeout:设置子进程最大运行时长,超时会抛出TimeoutExpired异常。
二、结合psutil监控最大内存消耗
要监控子进程的最大内存,需要借助psutil库轮询进程内存。下面的方案既保留了subprocess的输出捕获能力,又能自动监控内存峰值:
实现代码
import subprocess import psutil import time def run_process_with_monitor(cmd, timeout=100): # 启动子进程,非阻塞模式 proc = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True ) max_memory_mb = 0.0 start_time = time.time() try: # 轮询进程状态,直到结束或超时 while proc.poll() is None: # 检查超时 elapsed_time = time.time() - start_time if elapsed_time > timeout: proc.kill() raise subprocess.TimeoutExpired(cmd, timeout) # 获取当前内存使用量 try: process = psutil.Process(proc.pid) # RSS:进程实际占用的物理内存,转换为MB单位 current_mem = process.memory_info().rss / (1024 * 1024) if current_mem > max_memory_mb: max_memory_mb = current_mem except psutil.NoSuchProcess: break # 进程已意外结束 time.sleep(0.1) # 轮询间隔,可按需调整精度 # 读取所有输出内容 stdout, stderr = proc.communicate() return { "stdout": stdout, "stderr": stderr, "returncode": proc.returncode, "max_memory_mb": round(max_memory_mb, 2) } except subprocess.TimeoutExpired as e: stdout, stderr = proc.communicate() return { "stdout": stdout, "stderr": stderr, "returncode": -1, "max_memory_mb": round(max_memory_mb, 2), "error": "执行超时" } # 使用示例 if __name__ == "__main__": cmd = ["python", "test_script.py"] result = run_process_with_monitor(cmd, timeout=60) print(f"子进程最大内存消耗:{result['max_memory_mb']} MB") print(f"标准输出:\n{result['stdout']}")
关键说明
- 用
Popen启动进程后,通过communicate()读取输出,避免手动处理线程的繁琐,同时防止输出缓存导致的死锁; - 轮询过程中用
psutil.Process获取实时内存数据,动态更新内存峰值; - 手动实现超时检查,超时后立即终止进程并返回已捕获的结果;
- 轮询间隔
0.1秒可按需调整:间隔越小监控精度越高,但会增加少量CPU开销。
三、前置准备
运行代码前需要安装psutil库:
pip install psutil
内容的提问来源于stack exchange,提问作者BlueMonkey325
相关产品推荐
相关产品推荐

