在关键的应用程序中,监听程序的运行状态十分重要,因为其可以确保程序的平稳运行。本文将介绍如何使用Python实现这一功能,这里主要使用psutil
和subprocess
模块。同时,最后会提供一个完整的脚本案例供参考,用于监控并在目标程序意外停止时重启程序。
subprocess
模块是 Python 中用于创建和管理子进程的标准库模块。它允许你执行系统命令或其他可执行文件,获取它们的输出,以及与其交互。下面是一些 subprocess
模块的基本用法和示例:
你可以使用 subprocess.run()
函数来运行外部命令,并等待其完成:
import subprocess
# 运行一个简单的命令
result = subprocess.run(['ls', '-l'], capture_output=True, text=True)
# 打印命令输出
print(result.stdout)
['ls', '-l']
是一个示例命令,它列出当前目录的详细文件信息。capture_output=True
表示捕获命令的标准输出和标准错误输出。text=True
表示输出以文本字符串的形式返回,而不是字节。如果你希望命令在后台执行而不阻塞当前进程,可以使用 subprocess.Popen
类:
import subprocess
# 后台执行命令
process = subprocess.Popen(['python', 'target.py'])
# 等待命令完成
process.wait()
如果需要获取命令的输出,可以使用 subprocess.check_output()
函数:
import subprocess
# 获取命令输出
output = subprocess.check_output(['echo', 'Hello, subprocess!'], text=True)
# 打印输出
print(output)
有时候需要将数据传递给命令的标准输入。可以使用 subprocess.Popen.communicate()
方法来实现:
import subprocess
# 启动命令并传递输入
process = subprocess.Popen(['grep', 'Python'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True)
# 向命令输入数据
output, _ = process.communicate('Python is awesome!')
# 打印命令输出
print(output)
通过 subprocess.run()
或 subprocess.Popen.wait()
可以获取命令的返回值,通常是命令的退出代码。这可以帮助你判断命令是否成功执行。
psutil
(Python System and Process Utilities)模块是一个跨平台的库,提供了方便的接口来获取系统信息和管理进程。它可以用于监控系统资源的使用情况、管理进程以及执行系统管理任务。以下是 psutil
模块的一些主要功能和使用示例:
psutil
首先确保你已经安装了 psutil
模块。如果没有安装,可以通过 pip 安装:
pip install psutil
使用 psutil
可以轻松地获取系统的各种信息,如 CPU 使用率、内存使用情况、磁盘分区信息等。
import psutil
# 获取 CPU 逻辑核心数
cpu_count = psutil.cpu_count(logical=True)
print(f"CPU 逻辑核心数: {cpu_count}")
# 获取内存使用情况
memory = psutil.virtual_memory()
print(f"总内存: {memory.total / 1024 / 1024} MB")
print(f"已使用内存: {memory.used / 1024 / 1024} MB")
# 获取磁盘分区信息
disk_partitions = psutil.disk_partitions()
for partition in disk_partitions:
print(f"分区设备: {partition.device}, 文件系统: {partition.fstype}")
psutil
可以用来获取系统中运行的进程信息,包括进程列表、CPU 使用率、内存使用情况等。
import psutil
# 获取所有进程列表
all_processes = list(psutil.process_iter())
for proc in all_processes[:5]: # 打印前五个进程
print(f"进程名: {proc.name()}, PID: {proc.pid}")
# 获取指定 PID 进程的详细信息
pid = 1234 # 替换成你要查看的进程 PID
if psutil.pid_exists(pid):
process = psutil.Process(pid)
print(f"进程名称: {process.name()}")
print(f"进程状态: {process.status()}")
print(f"进程创建时间: {process.create_time()}")
print(f"进程 CPU 使用率: {process.cpu_percent(interval=1)}%")
print(f"进程内存使用情况: {process.memory_info().rss / 1024 / 1024} MB")
else:
print(f"PID {pid} 对应的进程不存在。")
psutil
还允许对进程进行管理操作,如终止进程、发送信号等。
import psutil
# 终止指定 PID 的进程
pid_to_terminate = 5678 # 替换成你要终止的进程 PID
if psutil.pid_exists(pid_to_terminate):
process = psutil.Process(pid_to_terminate)
process.terminate()
print(f"进程 {pid_to_terminate} 已终止。")
else:
print(f"PID {pid_to_terminate} 对应的进程不存在。")
使用 psutil
可以实现实时监控系统资源使用情况,例如在一个循环中获取 CPU 使用率:
import psutil
# 实时监控 CPU 使用率
while True:
cpu_percent = psutil.cpu_percent(interval=1)
print(f"当前 CPU 使用率: {cpu_percent}%")
这些示例展示了 psutil
模块在系统信息获取、进程管理和系统资源监控方面的基本用法。根据具体需求,你也可以进一步深入使用 psutil
的其他功能来实现更复杂的系统管理和监控任务。
下面是一个使用subprocess
模块来启动和监控一个Python程序的示例代码。后面将使用subprocess.Popen()
来启动程序,并通过process.poll()
来检查该进程是否仍在运行。如果目标程序停止运行,会获取其返回码,并根据返回码决定是否重新启动该程序。
具体代码如下所示:
import os
import subprocess
import sys
import time
import psutil # 导入 psutil 模块
def start_target_program(target_script):
# 显式指定Python解释器和环境变量
python_executable = sys.executable
env = dict(os.environ)
env['PYTHONPATH'] = ":".join(sys.path) # 将当前Python解释器的路径添加到PYTHONPATH环境变量中
# 在这里启动你的Python程序
return subprocess.Popen([python_executable, target_script], env=env)
def is_program_running(process):
# 检查程序是否在运行
return process.poll() is None
def bytes_to_readable(size_bytes):
# 将字节数转换为可读的格式(KB、MB、GB)
for unit in ['', 'KB', 'MB', 'GB']:
if size_bytes < 1024.0:
return f"{size_bytes:.2f} {unit}"
size_bytes /= 1024.0
def monitor_process(target_script):
# 启动被监测的程序
target_program = start_target_program(target_script)
while True:
# 检查并打印 CPU 利用率
cpu_percent = psutil.cpu_percent(interval=1)
print(f"当前 CPU 利用率:{cpu_percent}%")
# 获取并打印内存信息
memory_info = psutil.virtual_memory()
total_memory = bytes_to_readable(memory_info.total)
available_memory = bytes_to_readable(memory_info.available)
print(f"总内存: {total_memory}")
print(f"可用内存: {available_memory}")
# 获取并打印磁盘分区信息
disk_partitions = psutil.disk_partitions()
print("磁盘分区信息:")
for partition in disk_partitions:
print(f" 分区:{partition.device} 挂载点:{partition.mountpoint}")
# 检查程序是否在运行
if not is_program_running(target_program):
# 检查程序结束状态(是否是正常结束)
if target_program.returncode == 0:
print("被监测的程序已正常关闭。")
break
else:
print(f"被监测的程序已关闭,返回代码:{target_program.returncode}")
print("重启中...")
target_program = start_target_program(target_script)
else:
print("被监测的程序正常运行...")
# 每隔10分钟监听一次
time.sleep(600)
if __name__ == '__main__':
# 需要注意被监控脚本的路径和监控程序保持在同一目录下
target_script = input("请输入你需要监控的脚本名称(xxx.py):")
monitor_process(target_script)
通过结合使用 subprocess 和 psutil 模块,可以轻松实现对目标程序的监控和管理。
本文提供了一个简单的示例代码,展示了如何启动、监控和重启一个程序。希望这能帮助你更好地理解和使用 Python 进行系统和进程管理。