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 等操作系统.
1,psutil 模块安装
(1)源码安装 psutil
- git clone https://github.com/giampaolo/psutil.git
- cd psutil
- python3 setup.py install
(2)pip 安装
pip3 install psutil
(3)windows 上安装
C:\python35\python.exe -m pip install psutil
或者源码编译安装:
- make.bat build
- make.bat install
2, 获取 CPU 信息
In [10]: psutil.cpu_times(percpu=False) #查看 CPU 所有信息
Out[10]: scputimes(user=306.98, nice=2.01, system=337.34, idle=410414.39, iowait=78.37, irq=0.0, softirq=17.42, steal=0.0, guest=0.0, guest_nice=0.0)
- #user: 用户进程花费的时间
- #nice: 用户模式执行 Niced 优先级进程花费的时间
- #system: 内核模式进程花费的时间
- #idle: 闲置时间
- #iowait: 等待 I/O 完成的时间
- #irq: 处理硬件中断的时间
- #softirq: 处理软件中断的时间
- #steal: 虚拟化环境中运行的其他操作系统花费的时间
- #guest: 在 linux 内核的控制下为客户端操作系统运行虚拟 CPU 所花费的时间
- #guest_nice: 虚拟机运行 niced 所花费的时间
- # 显示 CPU 所有逻辑信息
- In [7]: psutil.cpu_times(percpu=True) #显示所有 CPU 逻辑信息
- Out[7]:
[scputimes(user=45.48, nice=0.31, system=69.41, idle=101285.67, iowait=19.67, irq=0.0, softirq=3.06, steal=0.0, guest=0.0, guest_nice=0.0),
scputimes(user=110.04, nice=0.46, system=70.63, idle=101210.2, iowait=22.99, irq=0.0, softirq=5.0, steal=0.0, guest=0.0, guest_nice=0.0),
scputimes(user=58.5, nice=0.5, system=126.64, idle=100934.59, iowait=14.47, irq=0.0, softirq=4.36, steal=0.0, guest=0.0, guest_nice=0.0),
scputimes(user=92.1, nice=0.72, system=68.3, idle=101146.96, iowait=21.12, irq=0.0, softirq=4.79, steal=0.0, guest=0.0, guest_nice=0.0)]
- # 显示用户占 CPU 的时间比
- In [11]: psutil.cpu_times().user #显示用户占 CPU 的时间比
- Out[11]: 307.11
- # 显示 CPU 逻辑个数和物理个数
- In [8]: psutil.cpu_count(logical=True) #显示 CPU 逻辑个数
- Out[8]: 4
- In [9]: psutil.cpu_count(logical=False) #显示 CPU 物理个数
- Out[9]: 4
- # 将各种 CPU 统计信息作为命名元组返回
- In [15]: psutil.cpu_stats() #CPU 统计信息
- Out[15]: scpustats(ctx_switches=9838934, interrupts=10572621, soft_interrupts=5582125, syscalls=0)
- #ctx_switches: 启动后的上下问切换次数
- #interrupts: 自启动以来的中断次数
- #soft_interrupts: 启动后的软件中断数量
- #syscalls: 启动以来的系统调用次数, 在 linux 上始终为 0
3, 内存信息
psutil.virtual_memory()以字节返回内存使用情况的统计信息
- In [20]: mem = psutil.virtual_memory() #获取内存完整信息
- In [21]: mem
Out[21]: svmem(total=2078892032, available=1508818944, percent=27.4, used=367063040, free=135192576, active=874614784, inactive=694231040, buffers=122880, cached=1576513536, shared=10444800, slab=255148032)
- #total: 总物理内存
- #available: 可用的内存
- #used: 使用的内存
- #free: 完全没有使用的内存
- #active: 当前正在使用的内存
- #inactive: 标记为未使用的内存
- #buffers: 缓存文件系统元数据使用的内存
- #cached: 缓存各种文件的内存
- #shared: 可以被多个进程同时访问的内存
- #slab: 内核数据结构缓存的内存
- In [22]: mem.total #获取内存总数
- Out[22]: 2078892032
- In [23]: mem.used #获取已使用内存
- Out[23]: 367063040
- In [24]: mem.free #获取空闲内存
- Out[24]: 135192576
- In [25]: psutil.swap_memory() #获取 swap 内存信息
- Out[25]: sswap(total=2148528128, used=270336, free=2148257792, percent=0.0, sin=0, sout=12288)
- #total: 以字节为单位的总交换内存
- #used: 以字节为单位使用交换内存
- #free: 以字节为单位的可用交换内存
- #percent: 使用百分比
- #sin: 系统从磁盘交换的字节数
- #sout: 系统从磁盘换出的字节数
4, 磁盘信息
psutil.disk_partitions(all=False): 返回所有安装的磁盘分区作为名称元组的列表, 包括设备, 安装点和文件系统类型, 类似于 Unix 上的'df'命令.
- In [25]: import psutil
- In [26]: psutil.disk_partitions(all=False) #获取磁盘完整信息
- Out[26]:
- [sdiskpart(device='/dev/sda3', mountpoint='/', fstype='xfs', opts='rw,seclabel,relatime,attr2,inode64,noquota'),
- sdiskpart(device='/dev/sda5', mountpoint='/home', fstype='xfs', opts='rw,seclabel,relatime,attr2,inode64,noquota'),
sdiskpart(device='/dev/sda1', mountpoint='/boot', fstype='xfs', opts='rw,seclabel,relatime,attr2,inode64,noquota')]
psutil.disk_usage(path): 将有关包含给定路径的分区的磁盘使用情况统计信息返回为指定元组, 包括以字节表示的, 总共, 已使用和空闲的空间以及百分比使用率, 如果路径存在则引发 OSError.
- In [30]: psutil.disk_usage('/') #获取分区使用情况
- Out[30]: sdiskusage(total=53660876800, used=3662462976, free=49998413824, percent=6.8)
- #total: 总的大小(字节)
- #used: 已使用的大小(字节)
- #free: 空闲的大小(字节)
- #percent: 使用百分比
- psutil.disk_io_counters(perdisk=False,nowrap=True) #将系统范围的磁盘 I/0 统计作为命名元组返回, 包括以下字段:
read_count: 读取次数
write_count: 写入次数
read_bytes: 读取的字节数
write_bytes: 写入的字节数
read_time: 从磁盘读取的时间(以毫秒为单位)
write_time: 写入磁盘的时间(毫秒为单位)
busy_time: 花费在实际 I/O 上的时间
read_merged_count: 合并读取的数量
write_merged_count: 合并写入次数
perdisk 为 True 时返回物理磁盘相同的信息; nowrap 为 True 它将检测并调整函数调用中的新值.
- In [32]: psutil.disk_io_counters(perdisk=True) #获取单个分区的 IO 信息
- Out[32]:
- {'fd0': sdiskio(read_count=0, write_count=0, read_bytes=0, write_bytes=0, read_time=0, write_time=0, read_merged_count=0, write_merged_count=0, busy_time=0),
- 'sda1': sdiskio(read_count=1003, write_count=25, read_bytes=5893632, write_bytes=2226176, read_time=1143, write_time=11298, read_merged_count=0, write_merged_count=1, busy_time=3976),
- 'sda2': sdiskio(read_count=51, write_count=2, read_bytes=2260992, write_bytes=12288, read_time=246, write_time=391, read_merged_count=0, write_merged_count=1, busy_time=545),
- 'sda3': sdiskio(read_count=15216, write_count=34370, read_bytes=456854528, write_bytes=2394566656, read_time=186146, write_time=3937459, read_merged_count=17, write_merged_count=37260, busy_time=156705),
5, 网络信息
psutil.net_io_counters(pernic=False,nowrap=True): 将系统范围的网络 I/O 统计信息作为命名元组返回, 包括以下属性:
bytes_sent: 发送的字节数
bytes_recv: 收到的字节数
packets_sent: 发送的数据包数量
packets_recv: 接收的数据包数量
errin: 接收时的错误总数
errout: 发送时的错误总数
dropin: 丢弃的传入数据包总数
dripout: 丢弃的传出数据包总数(在 OSX 和 BSD 上始终为 0)
如果 pernic 为 True 网络接口上安装的每个网络接口返回相同的信息, nowrap 为 True 时将检测并调整函数调用中的这些数字, 将旧值添加到新值, 保证返回的数字将增加或不变, 但不减少, net_io_counters.cache_clear()可用于使 nowrap 缓存失效.
- In [79]: psutil.net_io_counters(pernic=False,nowrap=True)
- Out[79]: snetio(bytes_sent=19487039, bytes_recv=301660567, packets_sent=123489, packets_recv=337983, errin=0, errout=0, dropin=0, dropout=0)
- In [81]: psutil.net_io_counters(pernic=True,nowrap=True)
- Out[81]:
- {'ens32': snetio(bytes_sent=17684066, bytes_recv=299856862, packets_sent=121275, packets_recv=335825, errin=0, errout=0, dropin=0, dropout=0),
'lo': snetio(bytes_sent=1812739, bytes_recv=1812739, packets_sent=2270, packets_recv=2270, errin=0, errout=0, dropin=0, dropout=0)}
psutil.net_connections(kind='inet'): 返回系统范围的套接字链接, 命令元组列表返回, 每个命名元组提供了 7 个属性:
fd: 套接字文件描述符.
family: 地址系列, http://docs.python.org//library/socket.html#socket.AF_INET , http://docs.python.org//library/socket.html#socket.AF_INET6 或 http://docs.python.org//library/socket.html#socket.AF_UNIX .
type: 地址类型, http://docs.python.org//library/socket.html#socket.SOCK_STREAM 或 http://docs.python.org//library/socket.html#socket.SOCK_DGRAM .
laddr
: 本地地址作为命名元组或 AF_UNIX 套接字的情况. 对于 UNIX 套接字, 请参阅下面的注释.
(ip, port)path
raddr: 远程地址是指定的元组, 或者是 UNIX 套接字的绝对地址. 当远程端点未连接时, 您将获得一个空元组 (AF_INET *) 或(AF_UNIX). 对于 UNIX 套接字, 请参阅下面的注释.(ip, port)path""
status: 表示 TCP 连接的状态.
pid: 打开套接字的进程的 PID, 如果是可检索的, 否则 None. 在某些平台 (例如 Linux) 上, 此字段的可用性根据进程权限而变化(需要 root).
kind 参数的值包括:
inet:ipv4 和 ipv6
- inet4:ipv4
- inet6:ipv6
- tcp:TCP
- tcp4:TCP over ipv4
- tcp6:TCP over ipv6
- udp:UDP
dup4: 基于 ipv4 的 udp
cpu6: 基于 ipv6 的 udp
Unix:UNIX 套接字(udp 和 TCP 协议)
all: 所有可能的家庭和协议的总和
- In [86]: psutil.net_connections(kind='tcp')
- Out[86]:
- [sconn(fd=3, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=9090), raddr=(), status='LISTEN', pid=103599),
- sconn(fd=4, family=<AddressFamily.AF_INET6: 10>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='::', port=22), raddr=(), status='LISTEN', pid=1179),
- sconn(fd=13, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=25), raddr=(), status='LISTEN', pid=1279),
- sconn(fd=10, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='0.0.0.0', port=3306), raddr=(), status='LISTEN', pid=70099),
- sconn(fd=3, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='0.0.0.0', port=22), raddr=(), status='LISTEN', pid=1179),
- sconn(fd=3, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.146.139', port=22), raddr=addr(ip='192.168.146.1', port=4238), status='ESTABLISHED', pid=122738),
- sconn(fd=12, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=9001), raddr=(), status='LISTEN', pid=103596),
- sconn(fd=14, family=<AddressFamily.AF_INET6: 10>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='::1', port=25), raddr=(), status='LISTEN', pid=1279)]
- In [87]: psutil.net_connections(kind='inet4')
- Out[87]:
- [sconn(fd=3, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=9090), raddr=(), status='LISTEN', pid=103599),
- sconn(fd=13, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=25), raddr=(), status='LISTEN', pid=1279),
- sconn(fd=10, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='0.0.0.0', port=3306), raddr=(), status='LISTEN', pid=70099),
- sconn(fd=3, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='0.0.0.0', port=22), raddr=(), status='LISTEN', pid=1179),
- sconn(fd=3, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='192.168.146.139', port=22), raddr=addr(ip='192.168.146.1', port=4238), status='ESTABLISHED', pid=122738),
- sconn(fd=6, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_DGRAM: 2>, laddr=addr(ip='0.0.0.0', port=68), raddr=(), status='NONE', pid=119605),
- sconn(fd=12, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='127.0.0.1', port=9001), raddr=(), status='LISTEN', pid=103596),
- sconn(fd=1, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_DGRAM: 2>, laddr=addr(ip='127.0.0.1', port=323), raddr=(), status='NONE', pid=741)]
psutil.net_if_addrs(): 以字典的方式返回系统上的每个网络接口的关联地址.
- In [88]: psutil.net_if_addrs()
- Out[88]:
- {'lo': [snic(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None),
- snic(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None),
- snic(family=<AddressFamily.AF_PACKET: 17>, address='00:00:00:00:00:00', netmask=None, broadcast=None, ptp=None)],
- 'ens32': [snic(family=<AddressFamily.AF_INET: 2>, address='192.168.146.139', netmask='255.255.255.0', broadcast='192.168.146.255', ptp=None),
- snic(family=<AddressFamily.AF_INET6: 10>, address='fe80::9853:19bb:b07b:89d4%ens32', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None),
- snic(family=<AddressFamily.AF_PACKET: 17>, address='00:50:56:31:d8:11', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
psutil.net_if_stats(): 将安装在系统上的网络接口的信息作为字典返回, 其中包括 isup 是否启动, duplex 双工模式, speed 速率, mtu 最大传输单位, 以字节表示
- In [89]: psutil.net_if_stats()
- Out[89]:
- {'ens32': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=1000, mtu=1500),
'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}
6, 其他系统信息
- IN[93]:import psutil,time
- In [94]: psutil.boot_time() #系统启动时间戳
- Out[94]: 1527457908.0
- In [96]: time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(psutil.boot_time
- ...: ())) #格式化时间
- Out[96]: '2018-05-28 05:51:48'
- In [97]: psutil.users() #返回当前链接的系统用户
- Out[97]:
- [suser(name='root', terminal='tty1', host='', started=1527050368.0, pid=769),
- suser(name='root', terminal='pts/0', host='192.168.146.1', started=1527559040.0, pid=122742),
- suser(name='root', terminal='pts/1', host='192.168.146.1', started=1527559040.0, pid=122761)]
7, 系统进程管理
- In [1]: import psutil
- In [2]: psutil.pids() #列出所有进程 PID
- Out[2]:
- [1,2,3,5,6,7,8,]
- In [3]: p = psutil.Process(1265) #实例化一个 Process 对象, 参数为进程 PID
- In [4]: p.name() #进程名
- Out[4]: 'mysqld'
- In [5]: p.exe() #进程 bin 路径
- Out[5]: '/usr/local/mysql-5.5.32/bin/mysqld'
- In [6]: p.cwd() #进程工作目录绝对路径
- Out[6]: '/mysql/data'
- In [7]: p.status() #进程状态
- Out[7]: 'sleeping'
- In [8]: p.create_time() #进程创建时间, 时间戳格式
- Out[8]: 1527642963.22
- In [9]: p.uids() #进程 UID 信息
- Out[9]: puids(real=1001, effective=1001, saved=1001)
- In [10]: p.gids() #进程 GID 信息
- Out[10]: pgids(real=1001, effective=1001, saved=1001)
- In [11]: p.cpu_times() #进程 CPU 时间信息, 包括 user,system 的 CPU 时间
- Out[11]: pcputimes(user=1.53, system=6.06, children_user=0.0, children_system=0.0)
- In [12]: p.cpu_affinity() #get 进程 CPU 亲和度, 如果设置进程 CPU 亲和度, 将 CPU 号作为参数即可
- Out[12]: [0, 1, 2, 3]
- In [13]: p.memory_info() #进程内存 rss,vms 信息
- Out[13]: pmem(rss=45268992, vms=460525568, shared=4399104, text=9420800, lib=0, data=425431040, dirty=0)
- In [14]: p.io_counters() #进程 IO 信息包括读写 IO 数及字节数
- Out[14]: pio(read_count=594, write_count=27, read_bytes=15859712, write_bytes=32768, read_chars=6917150, write_chars=1555)
- In [15]: p.connections() #返回发开进程 socket 的 namedutples 列表, 包括 fs,family,laddr 等信息
- Out[15]: [pconn(fd=10, family=<AddressFamily.AF_INET: 2>, type=<SocketKind.SOCK_STREAM: 1>, laddr=addr(ip='0.0.0.0', port=3306), raddr=(), status='LISTEN')]
- In [16]: p.num_threads() #进程开启的线程数
- Out[16]: 16
- In [17]: p.memory_percent() #进程内存利用率
- Out[17]: 2.177553778800572
psutil.process_iter(attrs=None,ad_value=None): 返回一个迭代器 process, 为本地机器上的所有正在运行的进程生成一个类实例.
psutil.pid_exists(pid): 检查给定的 PID 是否存在于当前进程列表中.
psutil.wait_procs(procs,timeout=None,callback=None): 等待 process 终止实例列表的便捷函数, 返回一个元组, 指示哪些进程已经消失, 哪些进程还活着.
class psutil.Popen(*args,**kwargs): 它启动一个子进程, 并完全像使用 subprocess.Popen 一样处理, 它还提供了所有 psutil.Process 类的方法. Popen 类的作用是获取用户启动的应用程序进程信息, 以便跟踪程序进程的运行状态.
- In [18]: import psutil
- In [19]: from subprocess import PIPE
- In [20]: p = psutil.Popen(["/usr/bin/python","-c","print('hello world')"],stdout=
- ...: PIPE)
- In [21]: p.name()
- Out[21]: 'python'
- In [22]: p.username()
- Out[22]: 'root'
- In [23]: p.communicate()
- Out[23]: (b'hello world\n', None)
进程过滤实例:
- In [25]: import psutil
- In [26]: from pprint import pprint as pp
- # 根据进程名查看系统中的进程名与 pid
- In [27]: pp([p.info for p in psutil.process_iter(attrs=['pid','name']) if 'python
- ...: 'in p.info['name']])
- [{'name': 'ipython3', 'pid': 2429}]
- In [28]: pp([p.info for p in psutil.process_iter(attrs=['pid','name']) if 'mysql'
- ...: in p.info['name']])
- [{'name': 'mysqld_safe', 'pid': 987}, {'name': 'mysqld', 'pid': 1265}]
- # 所有用户进程
- In [32]: import getpass
- In [33]: pp([(p.pid,p.info['name']) for p in psutil.process_iter(attrs=['name','u
- ...: sername']) if p.info['username'] == getpass.getuser()])
- [(1, 'systemd'),
- (2, 'kthreadd'),
- (3, 'ksoftirqd/0'),
- (5, 'kworker/0:0H'),
- (6, 'kworker/u256:0'),
- ...
- (5004, 'kworker/0:0')]
- # 查看积极运行的进程:
- In [37]: pp([(p.pid,p.info) for p in psutil.process_iter(attrs=['name','status'])
- ...: if p.info['status'] == psutil.STATUS_RUNNING])
- [(2429, {'name': 'ipython3', 'status': 'running'})]
- # 使用日志文件的进程
- In [38]: import os,psutil
- In [39]: for p in psutil.process_iter(attrs=['name','open_files']):
- ...: for file in p.info['open_files'] or []:
- ...: if os.path.splitext(file.path)[1] == '.log':
- ...: print("%-5s %-10s %s" % (p.pid,p.info['name'][:10],file.path
- ...: ))
- ...:
- 689 auditd /var/log/audit/audit.log
- 725 vmtoolsd /var/log/vmware-vmsvc.log
- 974 tuned /var/log/tuned/tuned.log
- # 消耗超过 5M 内存的进程:
- In [42]: pp([(p.pid,p.info['name'],p.info['memory_info'].rss) for p in psutil.pro
- ...: cess_iter(attrs=['name','memory_info']) if p.info['memory_info'].rss> 5
- ...: * 1024 * 1024])
- [(1, 'systemd', 7118848),
- (411, 'systemd-udevd', 6254592),
- (712, 'polkitd', 13553664),
- (716, 'abrtd', 5734400),
- (724, 'VGAuthService', 6262784),
- (725, 'vmtoolsd', 6426624),
- (974, 'tuned', 19648512),
- (1265, 'mysqld', 45268992),
- (2204, 'sshd', 5726208),
- (2429, 'ipython3', 37232640)]
- # 消耗量最大的 3 个进程
- In [43]: pp([(p.pid, p.info) for p in sorted(psutil.process_iter(attrs=['name', '...: memory_percent']), key=lambda p: p.info['memory_percent'])][-3:])
- [(974, {'memory_percent': 0.9451434561080659, 'name': 'tuned'}),
- (2429, {'memory_percent': 1.7909847854955845, 'name': 'ipython3'}),
- (1265, {'memory_percent': 2.177553778800572, 'name': 'mysqld'})]
- # 消耗最多 CPU 时间的前 3 个进程
- In [44]: pp([(p.pid, p.info['name'], sum(p.info['cpu_times'])) for p in sorted(ps
- ...: util.process_iter(attrs=['name', 'cpu_times']), key=lambda p: sum(p.info
- ...: ['cpu_times'][:2]))][-3:])
- [(1265, 'mysqld', 13.93),
- (2429, 'ipython3', 14.809999999999999),
- (725, 'vmtoolsd', 16.74)]
- # 导致最多 I/O 的前 3 个进程
- In [45]: pp([(p.pid, p.info['name']) for p in sorted(psutil.process_iter(attrs=['...: name', 'io_counters']), key=lambda p: p.info['io_counters'] and p.info['...: io_counters'][:2])][-3:])
- [(2429, 'ipython3'), (725, 'vmtoolsd'), (1, 'systemd')]
- # 前 3 个进程打开最多的文件描述符:
- In [46]: pp([(p.pid, p.info) for p in sorted(psutil.process_iter(attrs=['name', '...: num_fds']), key=lambda p: p.info['num_fds'])][-3:])
- [(377, {'name': 'systemd-journald', 'num_fds': 24}),
- (1, {'name': 'systemd', 'num_fds': 43}),
- (1307, {'name': 'master', 'num_fds': 91})]
了解更对内容请查看官方文档: psutil.readhtedocs.io http://psutil.readthedocs.io/en/latest/
来源: https://www.cnblogs.com/zhangxinqi/p/9106265.html