有没有一种干净的方法来测量子进程的最大内存消耗,同时仍然使用Python中的
subprocess
捕获标准输出(并且最好设置超时)?
使用
subprocess
的功能可以轻松完成捕获输出和设置超时:
output = subprocess.run(cmd, capture_output=True, timeout=100)
测量最大分配内存似乎需要轮询,即使用
psutil
,如本示例所示:Python 中的子进程内存使用情况。但这样,还需要实现捕获stdout,这很快就会变得混乱(subprocess
启动一个新线程来读取stdout)
您可以通过组合
subprocess
和 psutil
来测量子进程的最大内存消耗并捕获标准输出。
使用
subprocess.Popen
启动子进程。这样您就可以在子流程运行时与其进行交互。
使用 psutil
定期检查内存使用情况。
这是我之前项目中的一个示例实现:
import subprocess
import psutil
import time
def run_command_with_memory_tracking(cmd, timeout=None):
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
psutil_process = psutil.Process(process.pid)
max_memory = 0
start_time = time.time()
output, errors = "", ""
# polling loop
while True:
# measure memory
current_memory = psutil_process.memory_info().rss
max_memory = max(max_memory, current_memory)
if timeout and (time.time() - start_time) > timeout:
process.kill()
raise TimeoutError(f"Command '{' '.join(cmd)}' timed out after {timeout} seconds")
if process.poll() is not None:
break
time.sleep(0.1)
output, errors = process.communicate()
return {
"max_memory": max_memory,
"stdout": output,
"stderr": errors
}
# Test
cmd = ["echo", "Hello, World!"]
result = run_command_with_memory_tracking(cmd, timeout=10)
print(f"Max memory used: {result['max_memory']} bytes")
print(f"Output:\n{result['stdout']}")
print(f"Errors:\n{result['stderr']}")