psutil


psutil简介

psutil是一个跨平台库(http://pythonhosted.org/psutil/)能够轻松实现获取系统运行的进程和系统利用率(包括CPU、内存、磁盘、网络等)信息。

它主要用来做系统监控,性能分析,进程管理。它实现了同等命令行工具提供的功能,如ps、top、lsof、netstat、ifconfig、who、df、kill、free、nice、ionice、iostat、iotop、uptime、pidof、tty、taskset、pmap等。目前支持32位和64位的Linux、Windows、OS X、FreeBSD和Sun Solaris等操作系统。

Python 的 psutil(process and system utilities)是一个跨平台的系统监控和进程管理库,能够轻松获取系统资源使用情况(CPU、内存、磁盘、网络等)和进程详细信息(PID、状态、资源占用等)。它封装了底层系统调用,提供了统一的 API,支持 Windows、Linux、macOS 等主流操作系统,是编写系统监控工具、进程管理脚本的理想选择。

一、psutil 安装

psutil 是第三方库,需通过 pip 安装:

pip install psutil

二、系统资源监控

psutil 提供了丰富的接口获取系统硬件和资源使用状态,涵盖 CPU、内存、磁盘、网络等核心维度。

1. CPU 信息

获取 CPU 核心数、使用率、负载等信息。

import psutil

# 1. CPU 核心数(物理核心 + 逻辑核心)
print("物理核心数:", psutil.cpu_count(logical=False))  # 物理核心(如 4)
print("逻辑核心数:", psutil.cpu_count(logical=True))   # 逻辑核心(如 8,含超线程)

# 2. CPU 使用率(百分比)
# 注意:首次调用返回 0.0,需间隔一段时间再次调用(或指定 interval)
print("CPU 总使用率(1秒内):", psutil.cpu_percent(interval=1))  # 如 20.0%

# 3. 每个逻辑核心的使用率
print("各核心使用率:", psutil.cpu_percent(percpu=True, interval=1))  # 如 [10.0, 20.0, 5.0, 15.0, ...]

# 4. CPU 负载(1/5/15 分钟内的平均负载,Linux/macOS 有效)
print("CPU 负载(1/5/15分钟):", psutil.getloadavg())  # 如 (1.2, 0.8, 0.6)

2. 内存信息

获取物理内存和交换内存(swap)的总容量、已使用、可用量等。

# 1. 物理内存信息
mem = psutil.virtual_memory()
print("物理内存总量:", mem.total / 1024**3, "GB")  # 总容量(转为 GB)
print("已使用内存:", mem.used / 1024**3, "GB")    # 已使用
print("可用内存:", mem.available / 1024**3, "GB")  # 可用(含缓存/缓冲)
print("内存使用率:", mem.percent, "%")             # 使用率

# 2. 交换内存(swap)信息
swap = psutil.swap_memory()
print("交换内存总量:", swap.total / 1024**3, "GB")
print("交换内存使用率:", swap.percent, "%")

3. 磁盘信息

获取磁盘分区、使用率、IO 统计等。

# 1. 磁盘分区列表(类似 Linux 的 df -h)
partitions = psutil.disk_partitions()  # 获取所有挂载的分区
for part in partitions:
    print(f"分区:{part.device},挂载点:{part.mountpoint},文件系统:{part.fstype}")

# 2. 分区使用率(以系统根分区为例)
root_usage = psutil.disk_usage('/')  # Linux/macOS 根分区;Windows 可改为 'C:\\'
print("根分区总容量:", root_usage.total / 1024**3, "GB")
print("根分区使用率:", root_usage.percent, "%")

# 3. 磁盘 IO 统计(读写次数、字节数)
disk_io = psutil.disk_io_counters()
print("磁盘总读取字节:", disk_io.read_bytes / 1024**2, "MB")
print("磁盘总写入字节:", disk_io.write_bytes / 1024**2, "MB")
print("磁盘读取次数:", disk_io.read_count)
print("磁盘写入次数:", disk_io.write_count)

4. 网络信息

获取网络接口、流量统计、连接状态等。

# 1. 网络总流量(累计收发字节)
net_io = psutil.net_io_counters()
print("总接收字节:", net_io.bytes_recv / 1024**2, "MB")
print("总发送字节:", net_io.bytes_sent / 1024**2, "MB")
print("总接收包数:", net_io.packets_recv)
print("总发送包数:", net_io.packets_sent)

# 2. 各网络接口的流量(如 eth0、wlan0、以太网)
net_interfaces = psutil.net_io_counters(pernic=True)  # percpu=True 按接口统计
for iface, stats in net_interfaces.items():
    print(f"接口 {iface}:接收 {stats.bytes_recv/1024**2:.2f}MB,发送 {stats.bytes_sent/1024**2:.2f}MB")

# 3. 网络连接列表(需管理员权限,部分系统受限)
# 常用状态:LISTEN(监听)、ESTABLISHED(已连接)、TIME_WAIT(等待关闭)
connections = psutil.net_connections()
for conn in connections[:5]:  # 打印前5个连接
    print(f"本地地址:{conn.laddr},远程地址:{conn.raddr},状态:{conn.status},PID:{conn.pid}")

5. 其他系统信息

# 系统启动时间(转为可读格式)
boot_time = psutil.boot_time()  # 返回时间戳
import datetime
print("系统启动时间:", datetime.datetime.fromtimestamp(boot_time))

# 当前登录用户
users = psutil.users()
for user in users:
    print(f"登录用户:{user.name},终端:{user.terminal},登录时间:{datetime.datetime.fromtimestamp(user.started)}")

三、进程管理

psutil 能轻松获取进程列表、查询进程详情(资源占用、状态等),甚至控制进程(结束进程)。

1. 获取进程列表

# 1. 所有进程的 PID 列表
all_pids = psutil.pids()
print("所有进程 PID:", all_pids[:5])  # 打印前5个 PID

# 2. 遍历所有进程,获取基础信息
for pid in all_pids[:5]:  # 遍历前5个进程
    try:
        p = psutil.Process(pid)  # 通过 PID 获取进程对象
        print(f"PID:{pid},名称:{p.name()},状态:{p.status()}")
    except psutil.NoSuchProcess:
        # 进程可能已结束,忽略
        continue

2. 进程详细信息

通过 Process 对象获取单个进程的详细信息(资源占用、命令行、启动时间等)。

# 以当前 Python 进程为例(PID 可通过 os.getpid() 获取)
import os
current_pid = os.getpid()
p = psutil.Process(current_pid)

# 1. 基础信息
print("进程名称:", p.name())          # 如 "python.exe" 或 "python3"
print("进程状态:", p.status())        # 如 "running"(运行中)、"sleeping"(休眠)
print("进程命令行:", p.cmdline())     # 启动命令,如 ['python', 'script.py']
print("进程启动时间:", datetime.datetime.fromtimestamp(p.create_time()))

# 2. 资源占用
print("进程 CPU 使用率:", p.cpu_percent(interval=1), "%")  # 1秒内的CPU使用率
print("进程内存使用率:", p.memory_percent(), "%")          # 占系统内存的百分比
mem_info = p.memory_info()
print("进程内存占用(RSS):", mem_info.rss / 1024**2, "MB")  # 实际使用的物理内存

# 3. 其他信息
print("进程所属用户:", p.username())  # 进程所有者
print("进程打开的文件数:", p.num_fds())  # Linux/macOS 有效(文件描述符数量)

3. 进程控制(结束进程)

psutil 支持通过 terminate()(终止)、kill()(强制杀死)等方法结束进程(需对应权限)。

# 示例:结束指定 PID 的进程(谨慎使用!)
target_pid = 1234  # 替换为实际 PID
try:
    p = psutil.Process(target_pid)
    p.terminate()  # 发送终止信号(类似 Unix 的 SIGTERM)
    # p.kill()      # 强制杀死(类似 Unix 的 SIGKILL,无法捕获)
    print(f"进程 {target_pid} 已终止")
except psutil.NoSuchProcess:
    print(f"进程 {target_pid} 不存在")
except psutil.AccessDenied:
    print(f"无权限结束进程 {target_pid}(可能需要管理员权限)")

4. 进程筛选

根据名称、状态等条件筛选进程(如查找所有 Python 进程)。

# 查找所有名称包含 "python" 的进程
python_processes = [p for p in psutil.process_iter(['name', 'pid']) if 'python' in p.info['name'].lower()]

for p in python_processes:
    print(f"Python 进程:PID {p.info['pid']},名称 {p.info['name']}")

四、跨平台兼容性

psutil 对主流操作系统的支持非常完善,但部分接口存在平台差异:
- CPU 负载getloadavg()):仅支持 Linux/macOS,Windows 无此接口。
- 网络连接net_connections()):Windows 需管理员权限才能获取完整信息;Linux 需 CAP_NET_ADMIN 权限。
- 文件描述符num_fds()):Windows 不支持(可用 num_handles() 替代,获取句柄数)。

五、应用场景

psutil 适合以下场景:
1. 系统监控工具:实时展示 CPU、内存、磁盘、网络的使用率(如任务管理器简化版)。
2. 进程管理脚本:批量筛选、启动、终止进程(如杀死所有僵尸进程)。
3. 性能分析:跟踪程序运行时的资源占用,定位性能瓶颈。
4. 自动化运维:监控服务器资源,当使用率超过阈值时报警(如内存使用率 > 90% 时发送邮件)。

总结

psutil 是 Python 系统监控和进程管理的“瑞士军刀”,其优势在于:
- 跨平台:统一接口支持多系统,无需为不同 OS 编写适配代码。
- 功能全面:覆盖系统资源和进程的几乎所有关键信息。
- 易用性:API 设计简洁,无需了解底层系统调用细节。

无论是开发简单的监控脚本,还是复杂的系统管理工具,psutil 都能显著提升开发效率,是 Python 系统编程的必备库之一。

Install

psutil安装也相当方便:

  • windows平台直接使用pip安装即可。
pip install psutil  
  • Linux平台可以选择tar包方式安装。
wget https://pypi.python.org/packages/source/p/psutil/psutil-3.2.1.tar.gz --no-check-certificate
tar zxvf psutil-3.2.1.tar.gz
cd psutil-3.2.1
python setup.py install

CPU

  • 获取CPU逻辑核数。logical参数默认为True,指获取逻辑核数。
print(psutil.cpu_count(logical=True))
  • 获取CPU物理核数。
print(psutil.cpu_count(logical=False))
  • 以百分比的形式返回表示当前CPU的利用率的浮点数。interval参数必须设置为大于0,因为它测试的是时间间隔内的利用率。percpu参数为True则所有CPU利用率的浮点列表,列表的顺序在调用之间是一致的。
print(psutil.cpu_percent(interval=1, percpu=True))
  • 在特定模式下,返回CPU所花费的时间百分比。
print(psutil.cpu_times_percent(interval=1, percpu=True))  
  • 在特定模式下,返回CPU所花费的时间(单位为秒)。
print(psutil.cpu_times()) 
  • 将各种CPU统计信息作为命名元组返回。
print(psutil.cpu_stats()) 
  • 将CPU频率作为名称包返回,包括 以Mhz表示的当前,最小和最大频率。在Linux 当前频率上报告实时值,在所有其他平台上它代表名义上的“固定”值。如果percpu是True并且系统支持每CPU频率检索(仅限Linux),则为每个CPU返回频率列表,否则返回包含单个元素的列表。如果无法确定最小值和最大值,则将它们设置为0。
print(psutil.cpu_freq(percpu=True)) 

Memory

  • 获取内存使用情况。相关参数,单位(字节):

    • total,总大小。
    • available,可用内存。
    • used,已使用。
    • free,空闲。
    • percent,使用率。

    需要注意的是,已使用和可用不等于总和。

print(psutil.virtual_memory()) 
  • 获取交换分区内存统计信息。相关参数,单位(字节):
    • total,总大小。
    • used,已使用地swap内存。
    • free,空闲。
    • sin,系统累计从磁盘交换的字节数。
    • sout,系统累计从磁盘换出的字节数。
print(psutil.swap_memory())  

Disk

  • 返回所有磁盘分区信息。包括设备,挂载点和文件系统类型。
print(psutil.disk_partitions(all=False))
  • 返回指定磁盘的信息。相关参数,单位(字节):
    • total,总大小。
    • used,使用。
    • free,空闲。
    • percent,使用率。
print(psutil.disk_usage('C:\\'))   
for d in psutil.disk_partitions():
    if d[3] != 'cdrom':  # 排除windows中的cd驱动器
        item = psutil.disk_usage(d[0])
        print('磁盘 {0} 总大小 {1[0]} 使用 {1[1]} 空闲 {1[2]} 使用率 {1[3]}'.format(d[0], item))
'''
磁盘 C:\ 总大小 128034672640 使用 98801184768 空闲 29233487872 使用率 77.2
磁盘 E:\ 总大小 2000396320768 使用 1566692167680 空闲 433704153088 使用率 78.3
磁盘 F:\ 总大小 368532213760 使用 107016785920 空闲 261515427840 使用率 29.0
磁盘 G:\ 总大小 314572795904 使用 86216327168 空闲 228356468736 使用率 27.4
磁盘 M:\ 总大小 317093572608 使用 133029965824 空闲 184063606784 使用率 42.0
'''
  • 获取磁盘 I/O 统计信息。相关参数:
    • read_count,读取次数。
    • write_count,写入次数。
    • read_bytes,读取的字节数。
    • write_bytes,写入的字节数。
print(psutil.disk_io_counters())  

Network

  • 获取网络I/O信息。相关参数:
    • bytes_sent:发送的字节数
    • bytes_recv:接收的字节数
    • packets_sent:发送的包数
    • packets_recv:接收的数据包数
    • errin:接收时的错误总数
    • errout:发送时的错误总数
    • dropin:丢弃的传入数据包总数
    • dropout:丢弃的传出数据包总数(macOS和BSD总是0)
print(psutil.net_io_counters()) 
  • 获取系统的套接字信息。每个命名元组都提供7个属性:
    • fd:套接字文件描述符。如果连接引用当前进程,则可以将其传递给socket.fromfd 以获取可用的套接字对象。在Windows和SunOS上,它始终设置为-1
    • family:地址族,AF_INETAF_INET6AF_UNIX
    • type:地址类型,SOCK_STREAMSOCK_DGRAM
    • laddr:作为命名元组的本地地址或 AF_UNIX套接字的情况。对于UNIX套接字,请参阅下面的注释。(ip, port)``path
    • raddr:作为命名元组的远程地址或UNIX套接字的绝对地址。当远程端点未连接时,您将获得一个空元组(AF_INET *)或(AF_UNIX)。对于UNIX套接字,请参阅下面的注释。(ip, port)``path``""
    • status:表示TCP连接的状态。返回值是psutil.CONN_ *常量之一(字符串)。对于UDP和UNIX套接字,这总是如此 psutil.CONN_NONE
    • pid:打开套接字的进程的PID,如果可以检索,否则None。在某些平台(例如Linux)上,此字段的可用性会根据进程权限(需要root)而更改。
print(psutil.net_connections())
  • 获取网卡地址相关信息。相关参数:
    • family:地址族,AF_INETAF_INET6, 或者psutil.AF_LINK指MAC地址。
    • address:主NIC地址(始终设置)。
    • netmask:网络掩码地址(可能是None)。
    • 广播:广播地址(可能是None)。
    • ptp:代表“点对点”; 它是点对点接口(通常是VPN)上的目标地址。广播ptp是互斥的。可能是None
print(psutil.net_if_addrs())
  • 获取网卡的信息,相关参数:
    • isup:指示NIC是否已启动并运行的bool。
    • duplex:双工通信类型; 它可以是NIC_DUPLEX_FULLNIC_DUPLEX_HALFNIC_DUPLEX_UNKNOWN
    • speed:以兆位(MB)表示的NIC速度,如果无法确定(例如'localhost'),它将被设置为0
    • mtu:NIC的最大传输单位,以字节为单位。
print(psutil.net_if_stats())

其他信息

  • 获取系统进程pid
import os
import psutil
psutil.pids()  # 以列表的形式返回系统所有进程pid号
print([{psutil.Process(pid).name(): pid} for pid in psutil.pids()])   # 返回进程名称和pid的列表
os.system('taskkill /F /IM wmplayer.exe')   # 借助os模块强制杀死指定进程
  • 获取系统开机时间
import time
import psutil
print(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(psutil.boot_time())))  # 2019-05-28 08:16:31
  • 获取当前用户登录信息
print(psutil.users())  # [suser(name='Anthony', terminal=None, host='0.0.0.0', started=1559002601.0, pid=None)]
  • linux系统返回硬件温度。
print(psutil.sensors_temperatures())  # windows下抛出AttributeError: module 'psutil' has no attribute 'sensors_temperatures'
  • linux获取硬件风扇转速。
print(psutil.sensors_fans())
  • 返回电池信息。相关参数:
    • 百分比:电池剩余百分比。
    • secsleft:电池电量耗尽前剩余的秒数的粗略近似值。如果连接了交流电源线,则设置为 psutil.POWER_TIME_UNLIMITED。如果无法确定它被设置为psutil.POWER_TIME_UNKNOWN
    • power_pluggedTrue如果连接了交流电源线,False 如果没有,或者None无法确定。
print(psutil.sensors_battery())