讲师中心 微信公众号
AI工具推荐 视频效率加速

Python中Unix子进程的CPU时间与内存使用精确监控指南

夏强吖_3879

夏强吖_3879

发布时间:2025-12-05 13:08:27

|

790人浏览过

|

来源于php中文网

原创

Python中Unix子进程的CPU时间与内存使用精确监控指南

本文详细介绍了如何在python中利用subprocess、resource和psutil库精确监控unix子进程的cpu时间(用户态和系统态)及实时内存使用情况。重点阐述了resource.getrusage调用时机对cpu时间测量的关键影响,并提供了结合实时内存采样与正确cpu时间捕获的完整代码示例,旨在帮助开发者准确评估外部工具的性能表现。

引言:子进程性能监控的重要性

在许多场景下,例如运行生物信息学工具、批处理脚本或任何需要调用外部程序的Python应用中,准确监控这些子进程的性能至关重要。这不仅有助于评估不同工具或参数配置的效率,还能帮助识别性能瓶颈和优化资源使用。本教程将深入探讨如何使用Python标准库subprocess、resource以及第三方库psutil来精确测量子进程的CPU时间消耗和内存占用。

核心工具介绍

在开始实践之前,我们首先了解一下将要使用的关键Python库:

  • subprocess: Python的标准库,用于创建和管理新的进程。它提供了比os.system更强大的功能,允许我们更好地控制子进程的输入、输出和错误流,并获取其返回码。
  • resource: 这是一个Unix特有的模块,提供了查询和修改系统资源限制以及资源使用情况的功能。其中,resource.getrusage()函数是测量进程及其子进程CPU时间的关键。
  • psutil: 一个跨平台的第三方库,用于获取系统运行的进程和系统利用率(CPU、内存、磁盘、网络等)的详细信息。它对于实时监控内存使用情况非常有用。

精确测量CPU时间

测量子进程的CPU时间是评估其计算效率的核心指标。resource.getrusage()函数能够返回一个包含多种资源使用情况的对象,其中ru_utime(用户态CPU时间)和ru_stime(系统态CPU时间)是我们需要关注的。

关键点:resource.getrusage(resource.RUSAGE_CHILDREN)的调用时机

立即学习Python免费学习笔记(深入)”;

resource.getrusage(resource.RUSAGE_CHILDREN)用于获取当前进程所有已终止子进程的资源使用情况。这意味着,要准确测量子进程的CPU时间,必须在子进程完成执行并终止后才能调用此函数来获取其累计的CPU时间。如果在子进程仍在运行时或尚未终止时调用,它将不会包含该子进程的完整CPU时间。

python全能编程助手
python全能编程助手

SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、

下载

错误示例分析: 原始代码中,usage_end = resource.getrusage(resource.RUSAGE_CHILDREN)被放置在subprocess.Popen调用之后,但在r.poll()循环之前。这意味着当usage_end被调用时,子进程可能刚刚启动或尚未开始消耗显著的CPU时间,导致usage_end.ru_utime - usage_start.ru_utime计算结果为0。

正确做法: 将第二次resource.getrusage(resource.RUSAGE_CHILDREN)的调用移到确认子进程已终止的循环之后。

实时监控内存使用

虽然resource模块可以提供峰值内存使用(ru_maxrss),但psutil库提供了更灵活和实时的内存监控能力。我们可以通过周期性地采样系统或特定进程的内存信息,来了解子进程运行期间的内存占用趋势。

两种内存监控策略:

  1. 系统级内存监控(psutil.virtual_memory()): 这种方法获取的是整个系统的内存使用情况。当只有一个主要子进程在运行时,这种方法可以间接反映子进程对系统内存的影响。它提供了总内存、可用内存、已用内存和内存百分比等信息。

  2. 进程级内存监控(psutil.Process(pid).memory_info()): 如果需要更精确地了解特定子进程的内存使用,可以通过psutil.Process(pid)来获取该子进程的详细内存信息,例如常驻内存集大小(RSS)、虚拟内存大小(VMS)等。这通常是更推荐的做法,因为它排除了其他系统进程的影响。

本教程将主要演示系统级内存监控,并简要提及进程级监控的优势。

完整的性能监控实现

下面是一个结合了CPU时间测量和实时内存监控的Python脚本示例。

import sys
import os
import subprocess
import resource
import psutil
import time

def get_system_memory_info():
    """
    获取当前系统的内存使用信息(GB为单位)。
    """
    mem = psutil.virtual_memory()
    return {
        "total_memory": mem.total / (1024.0 ** 3),
        "available_memory": mem.available / (1024.0 ** 3),
        "used_memory": mem.used / (1024.0 ** 3),
        "memory_percentage": mem.percent
    }

def get_process_memory_info(pid):
    """
    获取指定PID进程的内存使用信息(MB为单位)。
    """
    try:
        process = psutil.Process(pid)
        mem_info = process.memory_info()
        return {
            "rss_mb": mem_info.rss / (1024.0 ** 2), # 常驻内存集大小
            "vms_mb": mem_info.vms / (1024.0 ** 2)  # 虚拟内存大小
        }
    except psutil.NoSuchProcess:
        return None # 进程可能已终止

def monitor_subprocess_performance(bioinformatics_tool, setups, resultdir, inputs, tbl_rep_file):
    """
    监控子进程的CPU时间与内存使用。
    """
    # 示例变量,实际应用中请替换为您的具体值
    # bioinformatics_tool = "your_bio_tool"
    # setups = "--some-setup-args"
    # resultdir = "/path/to/results"
    # inputs = "/path/to/input.fasta"
    # tbl_rep_file = "report_file.txt"

    print(f"开始监控工具: {bioinformatics_tool}")

    # 打开报告文件
    try:
        outrepfp = open(tbl_rep_file, "w")
    except IOError as e:
        sys.exit(f"错误: 无法打开报告文件 {tbl_rep_file}: {e}")

    SLICE_IN_SECONDS = 1 # 内存采样间隔

    # 1. 在子进程启动前记录资源使用
    usage_start = resource.getrusage(resource.RUSAGE_CHILDREN)

    # 2. 构建并执行子进程命令
    cmd = '{0} {1} --tblout {2} {3}'.format(bioinformatics_tool, setups, resultdir, inputs)
    print(f"执行命令: {cmd}")

    # 使用subprocess.Popen执行命令
    # 注意: stdout=subprocess.DEVNULL 将标准输出重定向到空设备
    # stderr=subprocess.PIPE 将标准错误捕获到管道中,以便后续检查
    try:
        r = subprocess.Popen(cmd.split(), stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, encoding='utf-8')
    except FileNotFoundError:
        sys.exit(f"错误: 命令 '{bioinformatics_tool}' 未找到。请检查路径或环境变量。")
    except Exception as e:
        sys.exit(f"错误: 执行子进程失败: {e}")

    # 3. 实时监控内存使用,直到子进程结束
    system_memory_snapshots = []
    process_memory_snapshots = []

    # 获取子进程的PID,用于进程级内存监控
    child_pid = r.pid 
    print(f"子进程PID: {child_pid}")

    while r.poll() is None: # 检查子进程是否仍在运行
        system_memory_snapshots.append(get_system_memory_info())

        # 也可以同时监控子进程自身的内存
        proc_mem = get_process_memory_info(child_pid)
        if proc_mem:
            process_memory_snapshots.append(proc_mem)

        time.sleep(SLICE_IN_SECONDS)

    # 确保在子进程终止后,再进行一次资源使用记录
    # 4. 子进程终止后记录资源使用,以获取准确的CPU时间
    usage_end = resource.getrusage(resource.RUSAGE_CHILDREN) 

    # 5. 检查子进程返回码,处理潜在错误
    if r.returncode != 0:
        error_output = r.stderr.strip()
        sys.exit(f'FAILED: 命令 "{cmd}" 失败,返回码 {r.returncode}\n错误输出:\n{error_output}')

    # 6. 提取并计算性能指标
    # 提取系统已用内存的最大值(从采样数据中)
    max_system_used_memory_gb = 0
    if system_memory_snapshots:
        max_system_used_memory_gb = max(m['used_memory'] for m in system_memory_snapshots)

    # 提取子进程峰值RSS内存(如果进行了进程级监控)
    max_process_rss_mb = 0
    if process_memory_snapshots:
        max_process_rss_mb = max(m['rss_mb'] for m in process_memory_snapshots)

    # 计算CPU时间
    cpu_time_user = usage_end.ru_utime - usage_start.ru_utime
    cpu_time_system = usage_end.ru_stime - usage_start.ru_stime
    total_cpu_time = cpu_time_user + cpu_time_system

    # 7. 将测量结果写入报告文件
    report_line = (
        f"{bioinformatics_tool} "
        f"用户CPU时间: {cpu_time_user:.4f}s "
        f"系统CPU时间: {cpu_time_system:.4f}s "
        f"总CPU时间: {total_cpu_time:.4f}s "
        f"峰值系统已用内存: {max_system_used_memory_gb:.2f}GB "
        f"峰值进程RSS内存: {max_process_rss_mb:.2f}MB\n"
    )
    outrepfp.write(report_line)
    outrepfp.close()

    print(f"性能报告已写入: {tbl_rep_file}")
    print(report_line.strip())

# 示例调用 (请根据您的实际情况修改参数)
if __name__ == "__main__":
    # 假设的参数
    tool_name = "example_tool"
    tool_setups = "-i input.txt -o output.txt"
    results_dir = "./results"
    input_data = "data.csv"
    report_file_name = "performance_report.txt"

    # 创建一个模拟的外部工具脚本
    # 在实际环境中,这会是您的真实生物信息学工具
    with open("example_tool", "w") as f:
        f.write("#!/bin/bash\n")
        f.write("echo 'Running example tool...' >&2\n")
        f.write("sleep 3 # 模拟工作3秒\n")
        f.write("echo 'Example tool finished.' >&2\n")
        f.write("exit 0\n")
    os.chmod("example_tool", 0o755) # 赋予执行权限

    # 创建模拟的results目录
    os.makedirs(results_dir, exist_ok=True)

    monitor_subprocess_performance(
        tool_name,
        tool_setups,
        results_dir,
        input_data,
        report_file_name
    )

    # 清理模拟文件
    os.remove("example_tool")
    os.rmdir(results_dir)

代码解析与注意事项

  1. get_system_memory_info(): 提供了系统整体的内存快照。这有助于了解子进程运行期间整个系统的内存压力。
  2. get_process_memory_info(pid): 这是一个增强功能,可以直接获取由pid标识的子进程的内存使用情况。rss_mb(常驻内存集)通常是衡量实际物理内存占用更重要的指标。
  3. usage_start 和 usage_end 的位置:
    • usage_start 必须在subprocess.Popen之前调用,以记录初始状态。
    • usage_end 必须在while r.poll() is None:循环之后调用,确保子进程已终止,resource模块才能准确汇总其CPU时间。
  4. while r.poll() is None: 循环: 这是等待子进程完成并进行实时监控的关键。r.poll()返回None表示子进程仍在运行,返回非None(通常是其返回码)表示子进程已终止。
  5. 内存采样间隔 SLICE_IN_SECONDS: 决定了内存监控的粒度。较小的值会增加开销但提供更精细的数据;较大的值开销小但可能错过瞬时峰值。
  6. 错误处理:
    • subprocess.Popen可能因命令不存在 (FileNotFoundError) 或其他原因失败。
    • 子进程本身可能以非零返回码结束,表示执行失败。r.returncode用于检查这一点,并通过r.stderr捕获错误输出。
  7. stdout=subprocess.DEVNULL 和 stderr=subprocess.PIPE:
    • DEVNULL将子进程的标准输出重定向到空设备,避免在控制台打印大量信息。
    • PIPE将标准错误捕获到Python脚本中,方便在子进程失败时进行检查和记录。
  8. CPU时间与墙钟时间(Wall-Clock Time):
    • resource模块测量的是CPU时间,即CPU实际花费在进程上的时间,不包括等待I/O或空闲的时间。
    • 如果需要测量墙钟时间(即从开始到结束的实际流逝时间),可以使用time.time()或time.monotonic()在进程启动前后进行记录。

总结

通过结合subprocess、resource和psutil库,我们可以构建一个强大而灵活的性能监控系统,用于评估Python中Unix子进程的CPU时间和内存使用。理解resource.getrusage的正确调用时机是获取准确CPU时间的关键,而psutil则提供了实时、细粒度的内存监控能力。遵循本教程中的方法和最佳实践,您将能够更有效地分析和优化您的外部工具和脚本的性能。

热门AI工具

更多
讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

相关专题

更多
resource是什么文件
resource是什么文件

Resource文件是一种特殊类型的文件,它通常用于存储应用程序或操作系统中的各种资源信息。它们在应用程序开发中起着关键作用,并在跨平台开发和国际化方面提供支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

320

2023.12.20

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

334

2023.09.25

unix和linux的区别
unix和linux的区别

unix和linux的区别包括发展历史、开源性、发行版本、内核、文件系统、应用程序兼容性和用户界面等。本专题为大家提供unix和linux相关的文章、下载、课程内容,供大家免费下载体验。

2253

2023.09.22

Vibeknow在线使用入口合集
Vibeknow在线使用入口合集

本专题汇总了Vibeknow在线创作视频的官方入口及网页版使用教程,涵盖PPT、PDF、Word等文档一键转讲解视频的核心操作,并整理了免费版水印规则与手机端浏览器访问指南,助你快速将知识内容视频化。

20

2026.09.21

NumPy随机数文件读写与dtype数据类型
NumPy随机数文件读写与dtype数据类型

本专题整理 NumPy 随机数、文件读写与 dtype 数据类型相关教程,覆盖 Generator/random、随机数种子、正态分布采样、npy/npz/CSV/TXT 保存读取、loadtxt/savetxt、memmap、大文件处理、astype 类型转换、结构化 dtype、整数溢出和精度丢失等场景。

0

2026.09.21

NumPy矩阵运算与线性代数计算
NumPy矩阵运算与线性代数计算

本专题整理 NumPy 矩阵运算与线性代数计算相关教程,覆盖矩阵乘法、dot 与 @ 运算符、逆矩阵、行列式、特征值与特征向量、SVD、线性方程组、欧氏距离、矩阵分解和大规模矩阵性能优化等内容,帮助读者掌握 np.linalg 与矩阵计算实战。

0

2026.09.21

NumPy广播机制数学运算与统计分析
NumPy广播机制数学运算与统计分析

本专题整理 NumPy 广播机制、数组数学运算与统计分析相关教程,覆盖广播规则、维度对齐、矩阵与数组加减除法、向量化计算、均值方差、分位数、中位数、直方图和 unique 频次统计等场景,帮助读者掌握 ndarray 高效计算与统计处理方法。

0

2026.09.21

NumPy数组创建索引切片与数据选择
NumPy数组创建索引切片与数据选择

本专题整理 NumPy 数组创建、索引、切片与数据选择相关教程,覆盖 np.array、zeros/ones、多维数组形状、基础切片、花式索引、布尔索引、条件筛选、视图与副本等常用场景,帮助读者系统掌握 ndarray 数据构造与高效提取方法。

0

2026.09.21

Aionclaw智能助手介绍
Aionclaw智能助手介绍

本专题汇总了AionClaw(AI龙虾助手)的功能介绍与在线使用入口。AionClaw是杭州趣猿人工智能有限公司推出的桌面级AI智能体,能直接在电脑上读写文件、运行脚本、操作浏览器,自动交付Word、PPT、Excel等成品。

40

2026.09.20

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn