`psutil` 库:系统进程与资源监控的高级应用

好的,各位听众,欢迎来到今天的“psutil 库:系统进程与资源监控的高级应用”讲座!今天咱们不搞那些虚头巴脑的,直接上干货,保证让大家听完之后,能用 psutil 库把你的电脑摸得门儿清!

一、psutil 是个啥玩意儿?

首先,咱们得搞清楚 psutil 是个啥。简单来说,psutil (process and system utilities) 是一个 Python 库,它提供了一个跨平台的方式来获取系统进程和系统利用率的信息。这意味着,无论你是用 Windows、macOS 还是 Linux,都可以用同一套代码来监控你的电脑。

想象一下,你的电脑就像一个繁忙的城市,各种进程就像在城市里跑来跑去的汽车,CPU、内存、磁盘就像城市的道路、停车场、仓库。而 psutil 就相当于一个城市交通监控系统,能告诉你现在有多少车在跑,哪些路堵了,哪个停车场快满了,哪个仓库没货了。

二、psutil 安装:工欲善其事,必先利其器

在开始之前,我们需要先安装 psutil 库。这个非常简单,打开你的终端或者命令提示符,输入:

pip install psutil

如果你的电脑上同时安装了 Python 2 和 Python 3,并且你想给 Python 3 安装,你可能需要使用 pip3

pip3 install psutil

安装完毕,我们就可以开始使用 psutil 了。

三、psutil 入门:初窥门径

咱们先来几个简单的例子,让大家对 psutil 有个初步的认识。

import psutil

# 获取 CPU 使用率
cpu_usage = psutil.cpu_percent(interval=1)  # 每隔 1 秒采样一次
print(f"CPU 使用率:{cpu_usage}%")

# 获取内存使用情况
memory = psutil.virtual_memory()
print(f"总内存:{memory.total / (1024 * 1024 * 1024):.2f} GB")  # 转换为 GB
print(f"可用内存:{memory.available / (1024 * 1024 * 1024):.2f} GB")
print(f"内存使用率:{memory.percent}%")

# 获取磁盘使用情况
disk = psutil.disk_usage('/')  # 根目录
print(f"总磁盘空间:{disk.total / (1024 * 1024 * 1024):.2f} GB")
print(f"已用磁盘空间:{disk.used / (1024 * 1024 * 1024):.2f} GB")
print(f"可用磁盘空间:{disk.free / (1024 * 1024 * 1024):.2f} GB")
print(f"磁盘使用率:{disk.percent}%")

# 获取网络信息
net_io = psutil.net_io_counters()
print(f"接收字节数:{net_io.bytes_recv / (1024 * 1024):.2f} MB")  # 转换为 MB
print(f"发送字节数:{net_io.bytes_sent / (1024 * 1024):.2f} MB")

这段代码会分别打印出 CPU 使用率、内存使用情况、磁盘使用情况和网络信息。注意,我们把字节数转换成了 MB 和 GB,这样看起来更直观。

四、进程管理:洞察秋毫

psutil 最强大的功能之一就是进程管理。它可以让你获取系统中所有进程的信息,甚至可以控制这些进程。

1. 获取所有进程

import psutil

for proc in psutil.process_iter(['pid', 'name', 'username']):
    print(f"PID: {proc.info['pid']}, 名称: {proc.info['name']}, 用户名: {proc.info['username']}")

这段代码会遍历系统中所有的进程,并打印出它们的 PID、名称和用户名。

2. 获取指定进程的信息

import psutil

pid = 1234  # 替换成你想要查询的进程的 PID
try:
    process = psutil.Process(pid)
    print(f"进程名称:{process.name()}")
    print(f"进程状态:{process.status()}")
    print(f"CPU 使用率:{process.cpu_percent(interval=1)}%")
    print(f"内存使用量:{process.memory_info().rss / (1024 * 1024):.2f} MB")  # 转换为 MB
    print(f"启动时间:{process.create_time()}")
    print(f"打开的文件:{process.open_files()}")
    print(f"线程数:{process.num_threads()}")
except psutil.NoSuchProcess:
    print(f"进程 {pid} 不存在")
except psutil.AccessDenied:
    print(f"没有权限访问进程 {pid}")

这段代码会获取指定 PID 的进程的信息,包括进程名称、状态、CPU 使用率、内存使用量、启动时间、打开的文件和线程数。需要注意的是,你可能需要管理员权限才能访问某些进程的信息。

3. 进程控制

psutil 还可以控制进程,例如杀死进程、改变进程优先级等。

import psutil
import os

pid = 1234  # 替换成你想要控制的进程的 PID
try:
    process = psutil.Process(pid)

    # 杀死进程
    # process.kill()  # 慎用!

    # 改变进程优先级 (仅在 Linux/macOS 上有效)
    # process.nice(psutil.BELOW_NORMAL_PRIORITY_CLASS)

    # 获取进程的 CPU 亲和性
    cpu_affinity = process.cpu_affinity()
    print(f"CPU 亲和性:{cpu_affinity}")

    # 设置进程的 CPU 亲和性 (需要管理员权限)
    # process.cpu_affinity([0, 1])  # 将进程绑定到 CPU 0 和 CPU 1

    # 获取进程的 I/O 优先级 (仅在 Windows 上有效)
    # io_priority = process.io_priority()

except psutil.NoSuchProcess:
    print(f"进程 {pid} 不存在")
except psutil.AccessDenied:
    print(f"没有权限访问进程 {pid}")
except OSError as e:
    print(f"操作系统错误:{e}")

这段代码展示了如何杀死进程、改变进程优先级、获取和设置进程的 CPU 亲和性。注意:杀死进程是一个危险的操作,请谨慎使用!

五、高级应用:更上一层楼

掌握了基本用法之后,咱们就可以开始探索 psutil 的高级应用了。

1. 监控系统资源

import psutil
import time

def monitor_system_resources(interval=1):
    """监控系统资源并打印信息"""
    try:
        while True:
            cpu_usage = psutil.cpu_percent(interval=interval)
            memory = psutil.virtual_memory()
            disk = psutil.disk_usage('/')
            net_io = psutil.net_io_counters()

            print(f"时间:{time.strftime('%Y-%m-%d %H:%M:%S')}")
            print(f"CPU 使用率:{cpu_usage}%")
            print(f"内存使用率:{memory.percent}%")
            print(f"磁盘使用率:{disk.percent}%")
            print(f"接收字节数:{net_io.bytes_recv / (1024 * 1024):.2f} MB")
            print(f"发送字节数:{net_io.bytes_sent / (1024 * 1024):.2f} MB")
            print("-" * 20)

    except KeyboardInterrupt:
        print("监控结束")

if __name__ == "__main__":
    monitor_system_resources()

这段代码会持续监控系统的 CPU、内存、磁盘和网络使用情况,并每隔一段时间打印出来。你可以根据自己的需求调整监控的频率。

2. 监控指定进程的资源使用情况

import psutil
import time

def monitor_process_resources(pid, interval=1):
    """监控指定进程的资源使用情况"""
    try:
        process = psutil.Process(pid)
        while True:
            cpu_usage = process.cpu_percent(interval=interval)
            memory_info = process.memory_info()
            memory_usage = memory_info.rss / (1024 * 1024)  # 转换为 MB
            io_counters = process.io_counters()
            read_bytes = io_counters.read_bytes / (1024 * 1024)  # 转换为 MB
            write_bytes = io_counters.write_bytes / (1024 * 1024)  # 转换为 MB

            print(f"时间:{time.strftime('%Y-%m-%d %H:%M:%S')}")
            print(f"进程名称:{process.name()}")
            print(f"CPU 使用率:{cpu_usage}%")
            print(f"内存使用量:{memory_usage:.2f} MB")
            print(f"读取字节数:{read_bytes:.2f} MB")
            print(f"写入字节数:{write_bytes:.2f} MB")
            print("-" * 20)

    except psutil.NoSuchProcess:
        print(f"进程 {pid} 不存在")
    except KeyboardInterrupt:
        print("监控结束")

if __name__ == "__main__":
    pid = 1234  # 替换成你想要监控的进程的 PID
    monitor_process_resources(pid)

这段代码会持续监控指定 PID 的进程的 CPU 使用率、内存使用量和 I/O 情况,并每隔一段时间打印出来。

3. 自定义监控指标

psutil 提供了丰富的 API,你可以根据自己的需求自定义监控指标。例如,你可以监控某个进程打开的文件数量,或者监控某个网络接口的流量。

import psutil
import time

def monitor_custom_metrics(interval=1):
    """监控自定义指标"""
    try:
        while True:
            # 监控打开的文件数量最多的进程
            processes = sorted(psutil.process_iter(['pid', 'name', 'open_files']),
                               key=lambda p: len(p.info['open_files']) if p.info['open_files'] else 0,
                               reverse=True)
            top_process = processes[0] if processes else None

            # 监控某个网络接口的流量
            net_io = psutil.net_io_counters(pernic=True)
            if '以太网' in net_io:  # 替换成你的网络接口名称
                eth_recv = net_io['以太网'].bytes_recv / (1024 * 1024)  # 转换为 MB
                eth_sent = net_io['以太网'].bytes_sent / (1024 * 1024)  # 转换为 MB
            else:
                eth_recv = 0
                eth_sent = 0

            print(f"时间:{time.strftime('%Y-%m-%d %H:%M:%S')}")
            if top_process:
                print(f"打开文件最多的进程:{top_process.info['name']} (PID: {top_process.info['pid']}), 打开文件数:{len(top_process.info['open_files'])}")
            else:
                print("没有进程正在运行")
            print(f"以太网接收流量:{eth_recv:.2f} MB")
            print(f"以太网发送流量:{eth_sent:.2f} MB")
            print("-" * 20)

            time.sleep(interval)

    except KeyboardInterrupt:
        print("监控结束")

if __name__ == "__main__":
    monitor_custom_metrics()

这段代码会监控打开文件数量最多的进程,以及某个网络接口的接收和发送流量。你需要根据自己的电脑环境修改网络接口的名称。

六、psutil 的一些小技巧

  • 使用 try...except 处理异常: 在使用 psutil 时,可能会遇到一些异常,例如 NoSuchProcess (进程不存在)、AccessDenied (没有权限访问) 等。使用 try...except 可以让你优雅地处理这些异常,避免程序崩溃。
  • 合理设置 interval 在使用 cpu_percent() 等方法时,需要设置 interval 参数,表示采样的时间间隔。如果 interval 设置得太小,可能会导致 CPU 使用率过高;如果 interval 设置得太大,可能会导致监控数据不准确。
  • 注意权限问题: 某些 psutil 方法需要管理员权限才能访问。如果没有管理员权限,可能会导致程序报错。
  • 结合其他库使用: psutil 可以和其他 Python 库结合使用,例如 matplotlib 可以用来可视化监控数据,smtplib 可以用来发送报警邮件。

七、psutil 的局限性

psutil 虽然强大,但也有一些局限性:

  • 性能开销: 频繁地调用 psutil 方法可能会导致一定的性能开销,尤其是在监控大量进程时。
  • 跨平台差异: 虽然 psutil 提供了跨平台的支持,但某些方法可能只在特定的操作系统上有效。
  • 信息安全: 使用 psutil 可以获取系统中的敏感信息,例如进程名称、用户名等。需要注意保护这些信息,避免泄露。

八、表格总结

为了方便大家回顾,我把 psutil 的一些常用方法整理成一个表格:

方法 描述 返回值类型
psutil.cpu_count() 获取 CPU 核心数 int
psutil.cpu_percent(interval=1) 获取 CPU 使用率,每隔 interval 秒采样一次 float
psutil.virtual_memory() 获取内存使用情况 svmem 对象
psutil.disk_usage(path) 获取磁盘使用情况,path 为磁盘路径 sdiskusage 对象
psutil.net_io_counters() 获取网络 I/O 统计信息 snicstats 对象
psutil.process_iter() 迭代所有进程 Process 对象迭代器
psutil.Process(pid) 获取指定 PID 的进程对象 Process 对象
process.name() 获取进程名称 str
process.status() 获取进程状态 str
process.cpu_percent(interval=1) 获取进程的 CPU 使用率,每隔 interval 秒采样一次 float
process.memory_info() 获取进程的内存信息 pmem 对象
process.kill() 杀死进程 (慎用!) None

九、实战案例:一个简单的系统监控程序

最后,我们来做一个简单的系统监控程序,它可以实时显示 CPU 使用率、内存使用率和磁盘使用率,并在 CPU 使用率超过 80% 时发出警告。

import psutil
import time

def system_monitor():
    """简单的系统监控程序"""
    while True:
        cpu_usage = psutil.cpu_percent(interval=1)
        memory = psutil.virtual_memory()
        disk = psutil.disk_usage('/')

        print(f"CPU 使用率:{cpu_usage}%")
        print(f"内存使用率:{memory.percent}%")
        print(f"磁盘使用率:{disk.percent}%")

        if cpu_usage > 80:
            print("警告:CPU 使用率过高!")

        time.sleep(1)

if __name__ == "__main__":
    system_monitor()

这个程序非常简单,但它可以让你对 psutil 的应用有一个更直观的了解。你可以根据自己的需求扩展这个程序,例如添加图形界面、发送报警邮件等。

十、总结

psutil 是一个非常强大的 Python 库,它可以让你轻松地获取系统进程和资源利用率的信息。掌握了 psutil,你就可以更好地了解你的电脑,优化你的程序,甚至可以开发出自己的系统监控工具。

希望今天的讲座对大家有所帮助! 感谢大家的收听! 祝大家编程愉快!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注