Go 怎样读取子进程资源使用量
Go 可以在子进程结束并完成等待后,通过 cmd.ProcessState 读取 CPU 时间,再从 SysUsage() 获取系统相关的资源信息。Linux 下可将其断言为 *syscall.Rusage,读取 Maxrss 等字段。它适合一次任务结束后的统计,不是正在运行进程的实时内存采样接口。
假设我为批处理作业增加一条资源报告,我会把“执行成功了吗”和“消耗了多少资源”分开记录。失败作业也可能已消耗大量 CPU 或内存,提前因 Wait 返回错误就退出,会丢掉有价值的信息。下面是这种取舍的 Linux 示例,不是实际作业测量报告。
Go 官方文档:https://pkg.go.dev/os#ProcessState.SysUsage、https://pkg.go.dev/os/exec#Cmd.Wait;Linux 字段说明:https://man7.org/linux/man-pages/man2/getrusage.2.html。
我会先把统计对象限定为这一次启动的任务
这里的 cmd 是 Go 启动的一条命令,ProcessState 对应完成等待后得到的退出信息,Rusage 是其系统资源记录。要得到这一次命令的结果,应使用这个 Cmd 的 ProcessState,而不是查询父进程自身的累计资源量。
我会选结束后统计来给离线作业做归档,因为无需持续采样,也没有采样间隔的配置成本。但代价很明确:不能据此画实时曲线,也不能依靠结束后的 Maxrss 实时阻止内存继续增长。本文只讨论 Rusage 与 Wait,不实现资源限制器或进程树监控。

普通执行权限就够,先保留真实启动错误
对子进程执行正常 Start 和 Wait,不需要为了读取该子进程退出后的统计而提升为 root。命令本身仍需要执行权限,工作目录、输入文件和环境也必须满足任务要求。如果文件不存在或不能执行,启动失败就没有这次成功运行后的资源报告,不能填一组零当作“任务未消耗资源”。
示例直接使用程序名称与参数列表,不经过 shell。对于来自不可信请求的命令,另行限制可执行程序与参数;资源统计不等于安全隔离。下面只适用于读者自己选择的可信命令。
Start 成功后,只让一个组件负责 Wait
将以下代码保存为 main_linux.go。构建约束故意限定 Linux,避免把系统特有字段与单位包装成所有系统通用接口。子进程输出交给标准错误流,资源摘要写入标准输出,避免把大段输出积存在内存缓冲区里。
//go:build linux
package main
import (
"fmt"
"os"
"os/exec"
"syscall"
"time"
)
func run() int {
if len(os.Args)
Start 之后必须安排等待以回收进程相关资源,但不能让多个组件竞争同一子进程的等待状态。若使用 cmd.Run,它已经负责启动和等待,也应在 Run 返回后读取 ProcessState,不要再调用 Wait。这里选择拆开写,是为了明确区分启动失败与已启动任务的失败。
# 在空的 Linux 示例目录中初始化模块。 go mod init example.com/usage-report # 构建资源记录程序。 go build -o usage-report . # 使用常见的只读版本查询命令演示参数传递。 ./usage-report go version
命令供读者执行,本文没有运行或提供虚构测量值。运行后应看到该命令的输出与摘要字段;具体 CPU 时间和内存量取决于环境,不能用固定数字作为验收依据。启动不存在的程序时应看到启动错误,不能声称得到完整 Rusage。
CPU 时间、墙钟耗时和峰值 RSS 不能互相替代
UserTime 与 SystemTime 分别提供用户态和内核态 CPU 时间,使用 Go 的 Duration 可避免手工转换 timeval 的秒与微秒。Go 文档描述的 CPU 口径包含已退出进程及其子进程;实际后代归集受到操作系统等待与资源记账规则影响,不能把它宣传为任意后台后代的完整监控。
wall 是示例在 Start 前到 Wait 返回的时间,包括启动、等待和运行经过的时间,不是纯 CPU 时间。多线程任务可以同时使用多个 CPU,累计 CPU 时间不必小于墙钟耗时;睡眠或等待 I/O 的任务则可能经历很长时间而消耗较少 CPU。
Linux 的 Maxrss 是峰值常驻集大小,单位 KiB。示例记录 max_rss_kib 和 max_rss_mib,不把它叫“当前内存”或“Go 堆内存”。不要把一次任务峰值当进程退出后仍然占用的内存,也不要将多个任务峰值简单相加当作同一时刻总量。

失败任务有统计,不代表执行已成功
对已经运行并以非零状态退出的命令,Wait 可能返回错误,ProcessState 仍可用于记录资源。我的处理方式是先检查状态是否存在,再采集字段,最后返回失败,避免成功率报表和资源报表互相覆盖。
还要区分进程退出状态与 Wait 本身遇到的问题。state.Success 和 ExitCode 描述进程退出;waitErr 描述等待或执行相关错误。被信号终止时,ExitCode 可能为 -1,不要机械解释成普通业务退出码。需要进一步分析退出原因时再按系统类型读取退出信息,不和 SysUsage 的资源数据混用。
| 情况 | 记录方式 |
|---|---|
| Start 失败 | 记录启动错误,不伪造资源量 |
| 已退出且状态可用 | 记录退出状态及系统可用资源字段 |
| Wait 返回非 nil 错误 | 保留可用统计,但任务结果仍失败 |
| 资源类型不可用 | 明确缺失,不用零值假装支持 |
累计子进程用量和跨平台单位要另写规则
能用 Getrusage(RUSAGE_CHILDREN) 替代吗?它提供调用进程已经等待回收的子进程累计口径,不是按指定 PID 查询这一次任务。父进程并发运行多个任务时,前后相减可能混入其他任务;Linux 文档还明确,其 Maxrss 是最大子进程的常驻集峰值,不是进程树总峰值。
能直接测整个 shell 流水线吗?示例统计自己启动并等待的命令,不承诺汇总任意管道或未被等待的后台后代。引入 shell 会改变被等待的对象,不能只看命令文本就确定统计覆盖面。
macOS 和 Windows 能照抄吗?不能。SysUsage 是系统相关返回值,Rusage 字段和单位应按目标平台分别确认。这里用 Linux 构建约束保留明确口径,不在其他系统直接输出同名 KiB 指标。
如果目标是离线作业归档,我会采用一次等待、一份退出状态、一组带平台和单位的资源字段;如果目标是实时监控或限制进程树用量,我会另选相应监控机制,而不扩大这份 Rusage 报告的能力。
Go os/user Current 和 Lookup 怎样选择
- 上一篇
- Go os/user Current 和 Lookup 怎样选择
- 下一篇
- Go XML Decoder Strict 关闭后适合什么兼容场景
-
- Golang · Go问答 | 1小时前 | go · RGBA image ColorModel At
- Go image 怎样读取不同颜色模型的像素
- 291浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go 怎样把 pprof 挂到独立 ServeMux
- 491浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go embed FS 打开不存在资源时怎样保留错误上下文
- 141浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go template.Funcs 怎样在 ParseFS 前注册自定义函数
- 406浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go XML Decoder Strict 关闭后适合什么兼容场景
- 412浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go os/user Current 和 Lookup 怎样选择
- 171浏览 收藏
-
- Golang · Go问答 | 1小时前 | 权限 · Go问答 · Go Unix Socket UnixConn 对端凭据 SO_PEERCRED x/sys/unix
- Go Unix socket 怎样读取对端凭据
- 302浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go Unix 数据报套接字怎样处理报文边界
- 336浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go 项目怎样为 HTTP/3 客户端划分可选依赖
- 471浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go HTTP/2 异常怎样用 GODEBUG 获取线索
- 366浏览 收藏
-
- Golang · Go问答 | 1小时前 |
- Go PGO 怎样合并多个代表性 profile
- 122浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 474次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 532次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 551次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 505次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 324次使用
-
- 用Nginx反向代理部署go写的网站。
- 2023-01-17 502浏览
-
- GoLand调式动态执行代码
- 2023-01-13 502浏览
-
- Go crypto/rand.Text 的长度为什么不是固定字符数
- 2026-10-04 501浏览
-
- Go strings.ToValidUTF8 清洗日志内容的边界
- 2026-10-03 501浏览
-
- Go tls.GetCertificate 为什么收不到空 ServerName 请求
- 2026-09-27 501浏览
