如何在特定进程运行时周期性执行nvidia-smi并确保无残留进程
在Bash中实现进程运行期间的GPU信息采集(无残留进程)
一、优先:基于nvidia-smi的原生循环采集方案
这种方案无需额外后台进程管理,直接通过循环检查目标进程存活状态,周期性执行nvidia-smi并写入日志:
#!/bin/bash # 配置参数 TARGET_PROC="./process1" GPU_LOG="logfile.txt" TIME_LOG="timelog.txt" INTERVAL=50 # 采集间隔(毫秒) # 启动目标进程并获取其PID $TARGET_PROC & PROC_PID=$! # 记录进程启动时间 echo "Process started at: $(date)" >> "$TIME_LOG" # 循环采集GPU信息,直到目标进程退出 while kill -0 $PROC_PID 2>/dev/null; do nvidia-smi >> "$GPU_LOG" # 将毫秒间隔转为sleep支持的秒级小数 sleep $(echo "scale=3; $INTERVAL/1000" | bc) done # 记录进程结束时间 echo "Process exited at: $(date)" >> "$TIME_LOG"
说明
kill -0 $PROC_PID仅检查进程是否存活,不会发送终止信号- 用
bc处理毫秒到秒的转换,保证间隔精度 - 全程无后台残留进程,循环会随目标进程终止自动结束
二、Bash后台进程管理方案(带陷阱清理)
如果要使用nvidia-smi -lms原生循环模式,可通过后台启动+陷阱机制,确保脚本无论正常/异常退出都能清理nvidia-smi进程:
#!/bin/bash # 配置参数 TARGET_PROC="./process1" GPU_LOG="logfile.txt" TIME_LOG="timelog.txt" INTERVAL=50 # 定义清理函数:终止nvidia-smi进程 cleanup() { [ -n "$SMI_PID" ] && { kill "$SMI_PID" 2>/dev/null wait "$SMI_PID" 2>/dev/null echo "nvidia-smi process terminated" } } # 设置陷阱:脚本退出(正常/中断)时执行清理 trap cleanup EXIT INT TERM # 启动nvidia-smi周期性采集并后台运行 nvidia-smi -lms "$INTERVAL" >> "$GPU_LOG" & SMI_PID=$! # 启动目标进程并记录运行时间 (time "$TARGET_PROC") >> "$TIME_LOG" 2>&1
说明
trap cleanup EXIT INT TERM覆盖了脚本正常结束、Ctrl+C中断、外部kill信号等所有退出场景wait "$SMI_PID"确保nvidia-smi完全退出,避免僵尸进程(time "$TARGET_PROC")将进程的运行时长和输出统一写入时间日志
关键注意事项
- 若目标进程是脚本或会fork子进程,建议用
pgrep -f "$TARGET_PROC"替代PID检查,避免漏判 - 如需每次运行清空日志,可在脚本开头添加
> "$GPU_LOG"和> "$TIME_LOG" - 确保当前用户有足够权限操作目标进程和
nvidia-smi
内容的提问来源于stack exchange,提问作者whoisit
相关产品推荐
相关产品推荐

