You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 08:10:02