您的位置:

全能编程开发工程师必备:深入解析psutil

一、psutil简介

Psutil是一个Python库,它能够获取有关运行进程和系统利用率(CPU,内存,磁盘,网络等)的信息。简而言之,它提供了一种Pythonic的方式来获取有关系统和进程的信息并允许操作系统管理进程和资源。

在本文中,我们将深入探讨如何使用psutil库获取系统和进程的不同信息,并且展示psutil如何让全能编程开发工程师更好地监测和优化他们的应用程序性能。

二、获取系统信息

Psutil提供了一个名为"system"的模块,用于获取关于系统的信息,例如系统时间、CPU计数器等等。例如:

import psutil

# 获取系统时间信息
system_time = psutil.boot_time()
print(f"System Time: {system_time}")

# 获取CPU逻辑核数
cpu_num = psutil.cpu_count()
print(f"CPU Number: {cpu_num}")

在这个示例中,我们使用boot_time()方法来获取系统启动时间,使用cpu_count()方法获取系统逻辑核数。

另外,psutil还可以获取当前系统的CPU利用率、内存使用情况、磁盘使用情况、网络活动情况等等。例如:

# 获取CPU利用率
cpu_usage = psutil.cpu_percent(interval=1)
print(f"CPU Usage: {cpu_usage}%")

# 获取内存使用情况
mem_info = psutil.virtual_memory()
print(f"Total Memory: {mem_info.total // (1024 * 1024)}MB")
print(f"Available Memory: {mem_info.available // (1024 * 1024)}MB")
print(f"Memory Usage: {mem_info.percent}%")

# 获取磁盘使用情况
disk_usage = psutil.disk_usage('/')
print(f"Total Disk Space: {disk_usage.total // (1024 * 1024 * 1024)}GB")
print(f"Used Disk Space: {disk_usage.used // (1024 * 1024 * 1024)}GB")
print(f"Free Disk Space: {disk_usage.free // (1024 * 1024 * 1024)}GB")

# 获取网络活动情况
net_io = psutil.net_io_counters()
print(f"Bytes Sent: {net_io.bytes_sent}")
print(f"Bytes Received: {net_io.bytes_recv}")

值得注意的是,大多数情况下我们需要每隔一段时间定时获取系统信息,因为实时获取有很高的CPU开销。在上面的示例中,我们在获取CPU利用率的时候使用了interval=1参数,表示每隔1秒钟获取一次CPU利用率。

三、获取进程信息

psutil库还可以通过"process"模块来获取每个正在运行的进程的相关信息,包括内存使用情况、CPU利用率、进程状态等。例如:

# 获取所有进程的PID
pid_list = psutil.pids()

# 循环获取每个进程的信息
for pid in pid_list:
    try:
        process = psutil.Process(pid)
        # 获取进程名
        process_name = process.name()
        # 获取进程状态
        process_status = process.status()
        # 获取进程CPU利用率
        process_cpu_percent = process.cpu_percent(interval=1)
        # 获取进程内存使用情况
        process_mem_info = process.memory_info()
        process_mem_percent = process.memory_percent()
        # 输出进程信息
        print(f"Process ID: {pid}")
        print(f"Process Name: {process_name}")
        print(f"Process Status: {process_status}")
        print(f"Process CPU Usage: {process_cpu_percent}%")
        print(f"Process Memory Usage: {process_mem_info.rss // (1024 * 1024)}MB ({process_mem_percent}%)")
    except psutil.NoSuchProcess:
        pass

在这个示例中,我们使用psutil.pids()方法获取所有正在运行的进程的PID。然后我们遍历所有进程,获取每个进程的相关信息,例如进程名、状态、CPU利用率、内存使用情况等等。

四、获取进程的子进程

在某些情况下,我们需要获取进程的子进程列表,例如在调试进程或者确保进程没有意外退出的时候。

# 获取指定进程的所有子进程
def get_child_process(pid):
    child_list = []
    for child in psutil.Process(pid).children(recursive=True):
        child_list.append(child.pid)
    return child_list

# 获取当前进程的所有子进程
this_process_id = os.getpid()
child_process_list = get_child_process(this_process_id)
print(f"Child Process List: {child_process_list}")

在这个示例中,我们使用psutil.Process(pid).children()方法获取指定进程的子进程,并且使用recursive=True参数让函数递归地获取子进程的子进程。

五、获取进程的打开句柄

句柄是与系统资源相关联的引用,例如文件、管道和网络连接等。在某些情况下,我们需要获取进程的所有打开句柄列表并分析它们。例如:

# 获取指定进程的所有打开句柄
def get_process_handles(pid):
    handle_list = []
    for handle in psutil.Process(pid).open_files():
        handle_list.append(handle.path)
    return handle_list

# 获取当前进程的所有打开句柄
this_process_id = os.getpid()
handle_list = get_process_handles(this_process_id)
print(f"Handle List: {handle_list}")

在这个示例中,我们使用psutil.Process(pid).open_files()方法获取指定进程的打开句柄列表。

六、获取进程的打开网络连接

在某些情况下,我们需要获取进程的打开网络连接列表,例如检测可能的恶意进程或者分析应用程序的网络行为。

# 获取指定进程的打开网络连接
def get_process_connections(pid):
    conn_list = []
    for conn in psutil.Process(pid).connections():
        conn_list.append((conn.laddr.ip, conn.laddr.port, conn.raddr.ip, conn.raddr.port))
    return conn_list

# 获取当前进程的所有打开网络连接
this_process_id = os.getpid()
conn_list = get_process_connections(this_process_id)
print(f"Connection List: {conn_list}")

在这个示例中,我们使用psutil.Process(pid).connections()方法获取指定进程的打开网络连接列表,并且返回一个由四个值组成的列表,包括本地IP地址、本地端口、远程IP地址和远程端口。

七、获取进程的CPU时间

在某些情况下,我们需要获取进程的CPU时间并分析它们,例如在编写高性能应用程序或者分析系统性能时。

# 获取指定进程的CPU时间
def get_process_cpu_time(pid):
    cpu_time = psutil.Process(pid).cpu_times()
    return cpu_time

# 获取当前进程的CPU时间
this_process_id = os.getpid()
cpu_time = get_process_cpu_time(this_process_id)
print(f"Process CPU Time: {cpu_time.user} User Seconds, {cpu_time.system} System Seconds")

在这个示例中,我们使用psutil.Process(pid).cpu_times()方法获取指定进程的CPU时间,并且打印用户和系统时间的秒数。

八、功能扩展:进程和CPU使用情况的图表展示

在大多数情况下,文本格式并不能很好地展现数据。因此我们可以使用常用的诸如matplotlib等,将系统和进程的CPU利用率以及内存使用情况转换成图表。

import psutil
import matplotlib.pyplot as plt

# 创建一个图形窗口,包括两个子图
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(8, 6))
plt.subplots_adjust(hspace=0.5)

# 获取系统CPU利用率和内存使用情况,并将它们添加到图形中
def plot_system_info(ax):
    cpu_usage = psutil.cpu_percent(interval=1)
    mem_usage = psutil.virtual_memory().percent
    ax.set_title("System Info")
    ax.set_xticks([])
    ax.set_ylabel("Usage (%)")
    ax.set_ylim([0, 100])
    ax.bar(["CPU Usage"], [cpu_usage])
    ax.bar(["Memory Usage"], [mem_usage])

# 获取最多使用CPU的进程,并将其信息添加到图形中
def plot_process_info(ax):
    processes = sorted(psutil.process_iter(), key=lambda p: p.cpu_percent(), reverse=True)
    most_cpu_usage_process = processes[0]
    cpu_usage = most_cpu_usage_process.cpu_percent(interval=1)
    mem_info = most_cpu_usage_process.memory_info()
    mem_usage = most_cpu_usage_process.memory_percent()
    ax.set_title(f"Process: {most_cpu_usage_process.name()}")
    ax.set_xticks([])
    ax.set_ylabel("Usage (%)")
    ax.set_ylim([0, 100])
    ax.bar(["CPU Usage"], [cpu_usage])
    ax.bar(["Memory Usage"], [mem_usage])

# 定期更新图形
while True:
    plot_system_info(ax1)
    plot_process_info(ax2)
    plt.pause(1)
    ax1.clear()
    ax2.clear()

在这个示例中,我们使用pyplot库将系统CPU利用率和内存使用情况以及最多使用CPU的进程的相关信息添加到图形中。然后我们使用一个无限循环,不断更新图形。

总结

通过本文的介绍,我们可以看出psutil库在全能编程开发工程师日常工作中的重要性。利用psutil库可以更好地获取系统和进程的相关信息,并且优化应用程序的性能。

希望本文能够帮助开发工程师更好地理解psutil库的各种功能,更加高效地工作。