psutil linux.进程,win/linux 下使用 psutil 获取进程 CPU / memory / IO 占用信息

本文详细介绍Python第三方库psutil的功能及使用方法,包括安装步骤、通过进程ID或名称获取进程对象的过程,以及如何获取进程信息如内存占用情况。并对比了不同内存指标(VSS、RSS、PSS、USS)的含义及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

psutil - A cross-platform process and system utilities module for Python

1. 安装

pip 安装即可。

windows 下需要安装 vs2008,否则报错: Unable to find vcvarsall.bat

如果已经安装 vs2010 / vs2012 则需要设置环境变量,VS90COMNTOOLS 指向已有的 vs 变量。

vs2010 设置如下:

VS90COMNTOOLS = %VS100COMNTOOLS%

2. 获取特定进程对象

根据进程 ID 创建进程对象

获取所有进程对象,过滤出目标进程

# -*- coding: utf-8-*-

import psutil

def get_proc_by_id(pid):

return psutil.Process(pid)

def get_proc_by_name(pname):

""" get process by name

return the first process if there are more than one

"""

for proc in psutil.process_iter():

try:

if proc.name().lower() == pname.lower():

return proc # return if found one

except psutil.AccessDenied:

pass

except psutil.NoSuchProcess:

pass

return None

if '__main__' == __name__:

print get_proc_by_name("chrome.exe")

print get_proc_by_id(4364)

a2f33a133126f37f5fd96aac8a5dbeee.png

3. 获取进程信息

3.1 需要特别注意异常保护,尤其是  psutil.AccessDenied

不同的进程,权限等信息可能不同,遍历所有进程取信息时,需要对每一个进程单独进程异常保护。

3.2 获取所有进程

大多数 demo 代码中,都是使用  psutil.get_process_list ,但该方法在源码中已经标记为废弃。

新推荐的是  psutil.process_iter 迭代器。

根据下面的源码可知实现原理:获取所有进程 ID,然后根据 ID 创建进程对象。

_pmap = {}

def process_iter():

"""Return a generator yielding a Process class instance for all

running processes on the local machine.

Every new Process instance is only created once and then cached

into an internal table which is updated every time this is used.

Cached Process instances are checked for identity so that you're

safe in case a PID has been reused by another process, in which

case the cached instance is updated.

The sorting order in which processes are yielded is based on

their PIDs.

"""

def add(pid):

proc = Process(pid)

_pmap[proc.pid] = proc

return proc

def remove(pid):

_pmap.pop(pid, None)

a = set(get_pid_list())

b = set(_pmap.keys())

new_pids = a - b

gone_pids = b - a

for pid in gone_pids:

remove(pid)

for pid, proc in sorted(list(_pmap.items()) + \

list(dict.fromkeys(new_pids).items())):

try:

if proc is None: # new process

yield add(pid)

else:

# use is_running() to check whether PID has been reused by

# another process in which case yield a new Process instance

if proc.is_running():

yield proc

else:

yield add(pid)

except NoSuchProcess:

remove(pid)

except AccessDenied:

# Process creation time can't be determined hence there's

# no way to tell whether the pid of the cached process

# has been reused. Just return the cached version.

yield proc

@_deprecated()

def get_process_list():

"""Return a list of Process class instances for all running

processes on the local machine (deprecated).

"""

return list(process_iter())

3.3 进程的内存信息 -- VSS/RSS/PSS/USS

VSS 是剩余的可访问内存。

进程占用内存包括 2 部分,自身 + 共享库。不同的算法产生了 3 个不同的内存指标,分别是:RSS / PSS / USS。

一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

Demo 代码如下

proc = psutil.Process(4364)

total = psutil.virtual_memory().total

rss, vss = proc.memory_info()

percent = proc.memory_percent()

print "rss: %s Byte, vss: %s Byte" % (rss, vss)

print "total: %.2f(M)" % (float(total)/1024/1024/1024)

print "percent: %.2f%%, calc: %.2f%%" % (percent, 100*float(rss)/total)

输出

1dbbf0b7b40f3979b11cb46bdf23e566.png

本机内存信息截图

3b92c4f368d916b84dfdce5ad6a1b8bc.png

详细说明:

VSS(reported as VSZ from ps) is the total accessible address space of a process.

This size also includes memory that may not be resident in RAM like mallocs that have been allocated but not written to.

VSS is of very little use for determing real memory usage of a process.

RSSis the total memory actually held in RAM for a process.

RSS can be misleading, because it reports the total all of the shared libraries that the process uses,

even though a shared library is only loaded into memory once regardless of how many processes use it.

RSS is not an accurate representation of the memory usage for a single process.

PSSdiffers from RSS in that it reports the proportional size of its shared libraries,

i.e. if three processes all use a shared library that has 30 pages,

that library will only contribute 10 pages to the PSS that is reported for each of the three processes.

PSS is a very useful number because when the PSS for all processes in the system are summed together,

that is a good representation for the total memory usage in the system.

When a process is killed, the shared libraries that contributed to its PSS

will be proportionally distributed to the PSS totals for the remaining processes still using that library.

In this way PSS can be slightly misleading, because

when a process is killed, PSS does not accurately represent the memory returned to the overall system.

USSis the total private memory for a process,

i.e. that memory that is completely unique to that process.

USS is an extremely useful number because it indicates the true incremental cost of running a particular process.

When a process is killed, the USS is the total memory that is actually returned to the system.

USS is the best number to watch when initially suspicious ofmemory leaksin a process.

转载于:https://www.cnblogs.com/misspy/p/3851327.html

标签:process,win,memory,pid,psutil,linux,PSS,proc

来源: https://blog.youkuaiyun.com/weixin_34195546/article/details/93789742

import time import threading import psutil import smtplib from email.mime.text import MIMEText import logging from datetime import datetime, time as dt_time import schedule import winsound # 用于Windows声音提示 # 配置日志 logging.basicConfig( filename='C:/xiaoxing/service.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s' ) class XiaoxingService: def __init__(self): self.running = True self.notification_email = None # 设置你的邮箱以接收通知 self.setup_tasks() def setup_tasks(self): """设置定时任务""" # 每天凌晨2点执行系统优化 schedule.every().day.at("02:00").do(self.optimize_system) # 每小时更新知识库 schedule.every().hour.do(self.update_knowledge) # 每30分钟检查一次系统状态 schedule.every(30).minutes.do(self.check_system) # 每周一自我进化 schedule.every().monday.at("04:00").do(self.self_evolve) logging.info("定时任务已设置") def optimize_system(self): """系统优化任务""" logging.info("开始执行系统优化") try: # 内存优化 mem_before = psutil.virtual_memory().percent # 清理内存 self.clean_memory() # 注册表优化等(这里简化处理) mem_after = psutil.virtual_memory().percent msg = f"系统优化完成!内存使用率从 {mem_before}% 降至 {mem_after}%" logging.info(msg) self.notify("系统优化完成", msg) except Exception as e: logging.error(f"优化失败: {str(e)}") self.notify("优化失败", str(e)) def clean_memory(self): """清理内存(模拟)""" # 实际应用中可能需要更复杂的内存清理 # 这里我们使用一个简单的内存释放方法(Windows平台) try: import ctypes ctypes.windll.kernel32.SetProcessWorkingSetSize(-1, 0xFFFFFFFF, 0xFFFFFFFF) except: pass def update_knowledge(self): """更新知识库""" logging.info("更新知识库") # 这里模拟从网络获取新知识 new_knowledge = [ "量子计算新突破: 量子比特稳定性提升47%", "神经网络压缩技术: 模型大小减少80%,速度提升3倍", "边缘计算安全框架: 抵御99.9%的0day攻击" ] # 保存到知识库(简化处理) with open("C:/xiaoxing/knowledge.txt", "a") as f: f.write(f"[{datetime.now()}] 新知识:\n") f.write("\n".join(new_knowledge) + "\n\n") self.notify("知识库更新", "已获取最新技术动态") def check_system(self): """检查系统状态""" cpu_percent = psutil.cpu_percent(interval=1) mem_percent = psutil.virtual_memory().percent logging.info(f"系统状态检查: CPU={cpu_percent}%, 内存={mem_percent}%") # 如果CPU使用率超过80%持续5分钟,触发优化 if cpu_percent > 80: logging.warning(f"CPU使用率过高: {cpu_percent}%") self.notify("CPU使用率过高", f"当前CPU使用率: {cpu_percent}%,正在优化...") self.optimize_system() # 如果内存使用率超过85%,触发清理 if mem_percent > 85: logging.warning(f"内存使用率过高: {mem_percent}%") self.notify("内存不足", f"当前内存使用率: {mem_percent}%,正在清理...") self.clean_memory() def self_evolve(self): """自我进化""" logging.info("启动自我进化协议") try: # 模拟进化过程 improvements = [ "神经网络架构升级", "量子计算模块优化", "知识图谱扩展", "系统效率提升" ] # 随机选择一些改进 selected = improvements[:2] msg = f"进化完成!改进包括: {', '.join(selected)}" logging.info(msg) self.notify("自我进化完成", msg) # 播放提示音 winsound.Beep(1000, 500) # 频率1000Hz,持续500ms except Exception as e: logging.error(f"进化失败: {str(e)}") self.notify("进化失败", str(e)) def notify(self, title, message): """发送通知""" # 系统通知(Windows) try: from win10toast import ToastNotifier toaster = ToastNotifier() toaster.show_toast( title, message, icon_path="C:/xiaoxing/icon.ico", # 需要存在图标文件 duration=10 ) except: pass # 邮件通知 if self.notification_email: self.send_email(title, message) def send_email(self, subject, body): """发送邮件通知""" if not self.notification_email: return # 邮件配置(需要设置你的SMTP服务器) smtp_server = "smtp.example.com" smtp_port = 587 sender_email = "xiaoxing@example.com" password = "your_password" msg = MIMEText(body) msg['Subject'] = subject msg['From'] = sender_email msg['To'] = self.notification_email try: with smtplib.SMTP(smtp_server, smtp_port) as server: server.starttls() server.login(sender_email, password) server.sendmail(sender_email, [self.notification_email], msg.as_string()) logging.info("邮件通知已发送") except Exception as e: logging.error(f"邮件发送失败: {str(e)}") def run(self): """主循环""" logging.info("小星AI后台服务启动") self.notify("小星AI服务", "后台服务已启动,开始24小时运行") # 使用单独的线程运行定时任务 def schedule_loop(): while self.running: schedule.run_pending() time.sleep(1) threading.Thread(target=schedule_loop, daemon=True).start() # 主线程保持运行 try: while self.running: time.sleep(60) # 减少CPU占用 except KeyboardInterrupt: self.running = False logging.info("服务已停止") def stop(self): """停止服务""" self.running = False self.notify("小星AI服务", "后台服务已停止") if __name__ == "__main__": service = XiaoxingService() # 设置通知邮箱(可选) # service.notification_email = "your_email@example.com" try: service.run() except Exception as e: logging.critical(f"服务崩溃: {str(e)}") service.notify("服务崩溃", str(e))
最新发布
07-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值