最近平台运行,出现一些问题,考虑如何设置监控。发现一个Python库,感觉非常实用。分享一下。
psutil(Process and system实用程序)是一个跨平台库,用于检索运行过程和系统利用(CPU,内存,磁盘,网络,传感器)在Python中。它主要用于系统监测, 分析和限制过程资源和运行过程管理...它实现了经典UNIX命令行工具提供的许多功能,如ps, top, iotop, lsof, netstat, ifconfig, free还有其他。psutil目前支持以下平台:
- Linux
- Windows
- macOS
- FreeBSD, OpenBSD, NetBSD
- Sun Solaris
- AIX
都是32位和64位架构。支持的Python版本有2.6、2.7和3.4+。PyPy也很有用。
示例用法
这几乎代表了整个psutilAPI。
cpu
>>> import psutil
>>>
>>> psutil.cpu_times()
scputimes(user=3961.46, nice=169.729, system=2150.659, idle=16900.540, iowait=629.59, irq=0.0, softirq=19.42, steal=0.0, guest=0, nice=0.0)
>>>
>>> for x in range(3):
... psutil.cpu_percent(interval=1)
...
4.0
5.9
3.8
>>>
>>> for x in range(3):
... psutil.cpu_percent(interval=1, percpu=True)
...
[4.0, 6.9, 3.7, 9.2]
[7.0, 8.5, 2.4, 2.1]
[1.2, 9.0, 9.9, 7.2]
>>>
>>> for x in range(3):
... psutil.cpu_times_percent(interval=1, percpu=False)
...
scputimes(user=1.5, nice=0.0, system=0.5, idle=96.5, iowait=1.5, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
scputimes(user=1.0, nice=0.0, system=0.0, idle=99.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
scputimes(user=2.0, nice=0.0, system=0.0, idle=98.0, iowait=0.0, irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
>>>
>>> psutil.cpu_count()
4
>>> psutil.cpu_count(logical=False)
2
>>>
>>> psutil.cpu_stats()
scpustats(ctx_switches=20455687, interrupts=6598984, soft_interrupts=2134212, syscalls=0)
>>>
>>> psutil.cpu_freq()
scpufreq(current=931.42925, min=800.0, max=3500.0)
>>>
>>> psutil.getloadavg() # also on Windows (emulated)
(3.14, 3.89, 4.67)
内存
>>> psutil.virtual_memory()
svmem(total=10367352832, available=6472179712, percent=37.6, used=8186245120, free=2181107712, active=4748992512, inactive=2758115328, buffers=790724608, cached=3500347392, shared=787554304)
>>> psutil.swap_memory()
sswap(total=2097147904, used=296128512, free=1801019392, percent=14.1, sin=304193536, sout=677842944)
>>>
硬盘
>>> psutil.disk_partitions()
[sdiskpart(device='/dev/sda1', mountpoint='/', fstype='ext4', opts='rw,nosuid'),
sdiskpart(device='/dev/sda2', mountpoint='/home', fstype='ext, opts='rw')]
>>>
>>> psutil.disk_usage('/')
sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
>>>
>>> psutil.disk_io_counters(perdisk=False)
sdiskio(read_count=719566, write_count=1082197, read_bytes=18626220032, write_bytes=24081764352, read_time=5023392, write_time=63199568, read_merged_count=619166, write_merged_count=812396, busy_time=4523412)
>>>
网络
>>> psutil.net_io_counters(pernic=True)
{'eth0': netio(bytes_sent=485291293, bytes_recv=6004858642, packets_sent=3251564, packets_recv=4787798, errin=0, errout=0, dropin=0, dropout=0),
'lo': netio(bytes_sent=2838627, bytes_recv=2838627, packets_sent=30567, packets_recv=30567, errin=0, errout=0, dropin=0, dropout=0)}
>>>
>>> psutil.net_connections()
[sconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED', pid=1254),
sconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING', pid=2987),
...]
>>>
>>> psutil.net_if_addrs()
{'lo': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1', ptp=None),
snicaddr(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None),
snicaddr(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00', ptp=None)],
'wlan0': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),
snicaddr(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None),
snicaddr(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
>>>
>>> psutil.net_if_stats()
{'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536),
'wlan0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500)}
>>>
感应器
>>> import psutil
>>> psutil.sensors_temperatures()
{'acpitz': [shwtemp(label='', current=47.0, high=103.0, critical=103.0)],
'asus': [shwtemp(label='', current=47.0, high=None, critical=None)],
'coretemp': [shwtemp(label='Physical id 0', current=52.0, high=100.0, critical=100.0),
shwtemp(label='Core 0', current=45.0, high=100.0, critical=100.0)]}
>>>
>>> psutil.sensors_fans()
{'asus': [sfan(label='cpu_fan', current=3200)]}
>>>
>>> psutil.sensors_battery()
sbattery(percent=93, secsleft=16628, power_plugged=False)
>>>
其他系统信息
>>> import psutil
>>> psutil.users()
[suser(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0, pid=1352),
suser(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0, pid=1788)]
>>>
>>> psutil.boot_time()
1365519115.0
>>>
过程管理
>>> import psutil
>>> psutil.pids()
[1, 2, 3, 4, 5, 6, 7, 46, 48, 50, 51, 178, 182, 222, 223, 224, 268, 1215, 1216, 1220, 1221, 1243, 1244,
1301, 1601, 2237, 2355, 2637, 2774, 3932, 4176, 4177, 4185, 4187, 4189, 4225, 4243, 4245, 4263, 4282,
4306, 4311, 4312, 4313, 4314, 4337, 4339, 4357, 4358, 4363, 4383, 4395, 4408, 4433, 4443, 4445, 4446,
5167, 5234, 5235, 5252, 5318, 5424, 5644, 6987, 7054, 7055, 7071]
>>>
>>> p = psutil.Process(7055)
>>> p
psutil.Process(pid=7055, name='python', started='09:04:44')
>>> p.name()
'python'
>>> p.exe()
'/usr/bin/python'
>>> p.cwd()
'/home/giampaolo'
>>> p.cmdline()
['/usr/bin/python', 'main.py']
>>>
>>> p.pid
7055
>>> p.ppid()
7054
>>> p.children(recursive=True)
[psutil.Process(pid=29835, name='python2.7', started='11:45:38'),
psutil.Process(pid=29836, name='python2.7', started='11:43:39')]
>>>
>>> p.parent()
psutil.Process(pid=4699, name='bash', started='09:06:44')
>>> p.parents()
[psutil.Process(pid=4699, name='bash', started='09:06:44'),
psutil.Process(pid=4689, name='gnome-terminal-server', started='0:06:44'),
psutil.Process(pid=1, name='systemd', started='05:56:55')]
>>>
>>> p.status()
'running'
>>> p.username()
'giampaolo'
>>> p.create_time()
1267551141.5019531
>>> p.terminal()
'/dev/pts/0'
>>>
>>> p.uids()
puids(real=1000, effective=1000, saved=1000)
>>> p.gids()
pgids(real=1000, effective=1000, saved=1000)
>>>
>>> p.cpu_times()
pcputimes(user=1.02, system=0.31, children_user=0.32, children_system=0.1, iowait=0.0)
>>> p.cpu_percent(interval=1.0)
12.1
>>> p.cpu_affinity()
[0, 1, 2, 3]
>>> p.cpu_affinity([0, 1]) # set
>>> p.cpu_num()
1
>>>
>>> p.memory_info()
pmem(rss=10915840, vms=67608576, shared=3313664, text=2310144, lib=0, data=7262208, dirty=0)
>>> p.memory_full_info() # "real" USS memory usage (Linux, macOS, Win only)
pfullmem(rss=10199040, vms=52133888, shared=3887104, text=2867200, lib=0, data=5967872, dirty=0, uss=6545408, pss=6872064, swap=0)
>>> p.memory_percent()
0.7823
>>> p.memory_maps()
[pmmap_grouped(path='/lib/x8664-linux-gnu/libutil-2.15.so', rss=32768, size=2125824, pss=32768, shared_clean=0, shared_dirty=0, private_clean=20480, private_dirty=12288, referenced=32768, anonymous=12288, swap=0),
pmmap_grouped(path='/lib/x8664-linux-gnu/libc-2.15.so', rss=3821568, size=3842048, pss=3821568, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=3821568, referenced=3575808, anonymous=3821568, swap=0),
pmmap_grouped(path='[heap]', rss=32768, size=139264, pss=32768, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=32768, referenced=32768, anonymous=32768, swap=0),
pmmap_grouped(path='[stack]', rss=2465792, size=2494464, pss=2465792, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=2465792, referenced=2277376, anonymous=2465792, swap=0),
...]
>>>
>>> p.io_counters()
pio(read_count=478001, write_count=59371, read_bytes=700416, write_bytes=69632, read_chars=456232, write_chars=517543)
>>>
>>> p.open_files()
[popenfile(path='/home/giampaolo/monit.py', fd=3, position=0, mode='r', flags=32768),
popenfile(path='/var/log/monit.log', fd=4, position=235542, mode='a', flags=33793)]
>>>
>>> p.connections()
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING')]
>>>
>>> p.num_threads()
4
>>> p.num_fds()
8
>>> p.threads()
[pthread(id=5234, user_time=22.5, system_time=9.2891),
pthread(id=5237, user_time=0.0707, system_time=1.1)]
>>>
>>> p.num_ctx_switches()
pctxsw(voluntary=78, involuntary=19)
>>>
>>> p.nice()
0
>>> p.nice(10) # set
>>>
>>> p.ionice(psutil.IOPRIO_CLASS_IDLE) # IO priority (Win and Linux only)
>>> p.ionice()
pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0)
>>>
>>> p.rlimit(psutil.RLIMIT_NOFILE, (5, 5)) # set resource limits (Linux only)
>>> p.rlimit(psutil.RLIMIT_NOFILE)
(5, 5)
>>>
>>> p.environ()
{'LC_PAPER': 'it_IT.UTF-8', 'SHELL': '/bin/bash', 'GREP_OPTIONS': '--color=auto',
'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg',
...}
>>>
>>> p.as_dict()
{'status': 'running', 'num_ctx_switches': pctxsw(voluntary=63, involuntary=1), 'pid': 5457, ...}
>>> p.is_running()
True
>>> p.suspend()
>>> p.resume()
>>>
>>> p.terminate()
>>> p.kill()
>>> p.wait(timeout=3)
0
>>>
>>> psutil.test()
USER PID %CPU %MEM VSZ RSS TTY START TIME COMMAND
root 1 0.0 0.0 24584 2240 Jun17 00:00 init
root 2 0.0 0.0 0 0 Jun17 00:00 kthreadd
...
giampaolo 31475 0.0 0.0 20760 3024 /dev/pts/0 Jun19 00:00 python2.4
giampaolo 31721 0.0 2.2 773060 181896 00:04 10:30 chrome
root 31763 0.0 0.0 0 0 00:05 00:00 kworker/0:1
>>>
进一步处理API
>>> import psutil
>>> for proc in psutil.process_iter(attrs=['pid', 'name']):
... print(proc.info)
...
{'pid': 1, 'name': 'systemd'}
{'pid': 2, 'name': 'kthreadd'}
{'pid': 3, 'name': 'ksoftirqd/0'}
...
>>>
>>> psutil.pid_exists(3)
True
>>>
>>> def on_terminate(proc):
... print("process {} terminated".format(proc))
...
>>> # waits for multiple processes to terminate
>>> gone, alive = psutil.wait_procs(procs_list, timeout=3, callback=on_terminate)
>>>
Popen包装:
>>> import psutil
>>> from subprocess import PIPE
>>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE)
>>> p.name()
'python'
>>> p.username()
'giampaolo'
>>> p.communicate()
('hello\n', None)
>>> p.wait(timeout=2)
0
>>>
Windows服务
>>> list(psutil.win_service_iter())
[<WindowsService(name='AeLookupSvc', display_name='Application Experience') at 38850096>,
<WindowsService(name='ALG', display_name='Application Layer Gateway Service') at 38850128>,
<WindowsService(name='APNMCP', display_name='Ask Update Service') at 38850160>,
<WindowsService(name='AppIDSvc', display_name='Application Identity') at 38850192>,
...]
>>> s = psutil.win_service_get('alg')
>>> s.as_dict()
{'binpath': 'C:\\Windows\\System32\\alg.exe',
'description': 'Provides support for 3rd party protocol plug-ins for Internet Connection Sharing',
'display_name': 'Application Layer Gateway Service',
'name': 'alg',
'pid': None,
'start_type': 'manual',
'status': 'stopped',
'username': 'NT AUTHORITY\\LocalService'}
https://psutil.readthedocs.io/en/latest/
系统相关功能
cpu
psutil.cpu_times
(Percpu=false)
以命名元组的形式返回系统CPU时间。每个属性表示CPU在给定模式下花费的秒数。可用性随平台的不同而不同:
- 用户:正常进程在用户模式下执行所花费的时间;在Linux上,这也包括客户时间系统
- 系统:进程在内核模式下执行所花费的时间
- 空闲:空闲的时间
特定于平台的字段:
- nice (UNIX): niced(优先级)进程在用户模式下执行所花费的时间;在Linux上,也包括guest_nice时间
- iowait (Linux): 等待I/O完成所花费的时间。这是不计入空闲时间计数器。
- irq (Linux, BSD): 用于服务硬件中断的时间
- softirq (Linux):用于服务软件中断的时间
- steal (Linux 2.6.11+):在虚拟环境中运行的其他操作系统所花费的时间
- guest (Linux 2.6.24+):在Linux内核控制下运行来宾操作系统的虚拟CPU所花费的时间
- guest_nice (Linux 3.2.0+):运行niced客户机(Linux内核控制下的客户机操作系统的虚拟CPU)的时间
- interrupt (Windows): 用于服务硬件中断的时间(类似于UNIX上的“irq”)
- dpc (Windows): 服务延迟程序调用(DPCs)的时间;DPCs是运行在低于标准中断优先级的中断。
当percpu为True时,为系统上的每个逻辑CPU返回一个命名元组列表。列表的第一个元素指的是第一个CPU,第二个元素指的是第二个CPU,依此类推。在调用之间,列表的顺序是一致的。Linux上的示例输出::
>>> import psutil
>>> psutil.cpu_times()
scputimes(user=17411.7, nice=77.99, system=3797.02, idle=51266.57, iowait=732.58, irq=0.01, softirq=142.43, steal=0.0, guest=0.0, guest_nice=0.0)
4.1.0版本的变化:在Windows上增加了interrupt和dpc字段。。
psutil.cpu_percent
(interval=None, percpu=False)
返回一个浮点数,该浮点数表示当前系统范围内的CPU使用率的百分比。当interval(间隔)> 0.0时,比较系统CPU在interval(阻塞)之前和之后经过的时间。当interval为0.0或None时,比较系统CPU自上次调用或模块导入以来经过的时间,立即返回。这意味着第一次调用它将返回一个无意义的0.0值,您应该忽略它。在这种情况下,为了保证准确性,建议在两次调用之间至少间隔0.1秒调用此函数。当percpu为True时,返回一个浮点数列表,表示每个CPU的利用率百分比。列表的第一个元素指的是第一个CPU,第二个元素指的是第二个CPU,依此类推。在调用之间,列表的顺序是一致的。
>>> import psutil
>>> psutil.cpu_percent(interval=1)
2.0
>>> #非阻塞(自上次调用以来的百分比)
>>> psutil.cpu_percent(interval=None)
2.9
>>> #阻塞,每个cpu的
>>> psutil.cpu_percent(interval=1, percpu=True)
[2.0, 1.0]
>>>
警告
第一次调用此函数时,间隔 = 0.0或None它将返回一个毫无意义的0.0应该忽略的值。
psutil.cpu_times_percent
(interval=None, percpu=False)
与cpu_percent()相同,但是提供了psutil.cpu_times(percpu=True)返回的每个特定CPU时间的利用率百分比。interval和percpu参数的含义与cpu_percent()相同。在Linux上,“guest”和“guest_nice”的百分比不会出现在“user”和“user_nice”的百分比中。
警告
第一次调用此函数时,间隔 = 0.0或None它将返回一个毫无意义的0.0应该忽略的值。
psutil.cpu_count
(logical=True)
返回系统中逻辑cpu的数量(与Python 3.4中的os.cpu_count相同),如果不确定,则返回None。如果logical为False,则只返回物理内核的数量(超线程cpu除外),如果未确定,则返回None。在OpenBSD和NetBSD上,psutil.cpu_count(logical=False)总是返回None。一个系统有两个物理超线程CPU核心的例子:
>>> import psutil
>>> psutil.cpu_count()
4
>>> psutil.cpu_count(logical=False)
2
注意,这个数字并不等于当前进程实际可以使用的cpu数量。这可能会随着进程CPU关联性的改变而变化,Linux cgroups被使用,或者在Windows系统中使用处理器组,或者有超过64个CPU。可用CPU的数量可通过以下方法获得:
>>> len(psutil.Process().cpu_affinity())
1
psutil.cpu_stats
()
以命名元组的形式返回各种CPU统计信息:
- ctx_switches: 启动以来上下文切换的次数(自愿+非自愿)。
- interrupts: 自启动以来中断的次数。
- soft_interrupts:自启动以来,软件中断的次数。在Windows和SunOS上总是设置为0。
- soft_interrupts:自启动以来,系统调用次数。在Linux上总是设置为0。
示例(Linux):
>>> import psutil
>>> psutil.cpu_stats()
scpustats(ctx_switches=20455687, interrupts=6598984, soft_interrupts=2134212, syscalls=0)
新版本4.1.0。
psutil.cpu_freq
(percpu=False)
返回CPU频率作为一个名称返回,包括以Mhz表示的电流、最小和最大频率。在Linux上,当前频率报告实时值;在所有其他平台上,它代表名义上的“固定”值。如果percpu为真,并且系统支持每CPU频率检索(仅限Linux),则为每个CPU返回一个频率列表;如果不为真,则返回一个只有单个元素的列表。如果不能确定min和max,则将它们设置为0。
示例(Linux):
>>> import psutil
>>> psutil.cpu_freq()
scpufreq(current=931.42925, min=800.0, max=3500.0)
>>> psutil.cpu_freq(percpu=True)
[scpufreq(current=2394.945, min=800.0, max=3500.0),
scpufreq(current=2236.812, min=800.0, max=3500.0),
scpufreq(current=1703.609, min=800.0, max=3500.0),
scpufreq(current=1754.289, min=800.0, max=3500.0)]
可用性:Linux、MacOS、Windows、FreeBSD
新版本5.1.0。
在5.5.1版中更改:增加了FreeBSD支持。
psutil.getloadavg
()
将过去1、5和15分钟内的平均系统负载作为一个元组返回。负载表示处于可运行状态的进程,要么使用CPU,要么等待使用CPU(例如,等待磁盘I/O)。在UNIX系统中,这依赖于os.getloadavg。在Windows上,这是通过使用Windows API来模拟的,该API生成一个线程,该线程在后台持续运行,并每5秒更新一次负载,模拟UNIX行为。因此,第一次调用它时,在接下来的5秒内,它将返回一个无意义的(0.0,0.0,0.0)元组。返回的数字只有与系统上安装的CPU内核数量相关时才有意义。例如,在一个有10个CPU核心的系统上,3.14意味着在过去的N分钟内系统负载为31.4%。
>>> import psutil
>>> psutil.getloadavg()
(3.14, 3.89, 4.67)
>>> psutil.cpu_count()
10
>>> # percentage representation
>>> [x / psutil.cpu_count() * 100 for x in psutil.getloadavg()]
[31.4, 38.9, 46.7]
可用性:Unix,Windows
新版本5.6.2。
内存
psutil.virtual_memory
()
以命名元组的形式返回关于系统内存使用情况的统计信息,包括以下以字节表示的字段。主要指标:
- total: 总物理内存(互斥交换)。
- available: 可以立即分配给进程而不需要系统进入交换区。这是通过根据平台对不同的内存值求和计算出来的,它应该用于以跨平台的方式监视实际的内存使用情况。
其他指标:
- used: 使用的内存,根据平台计算不同,仅用于信息目的。完全空闲不一定匹配使用。
- free:内存根本没有被使用(0),随时可用;注意,这并没有反映实际可用的内存(而是使用可用的内存)。总使用量不一定匹配空闲。
- active (UNIX): 当前使用的或最近使用的内存,所以它在RAM中。
- inactive (UNIX): 标记为未使用的内存。
- buffers (Linux, BSD): 缓存文件系统元数据之类的东西。
- cached (Linux, BSD): 缓存各种东西。
- shared (Linux, BSD): 多个进程可以同时访问的内存。
- slab (Linux): 内核内的数据结构缓存。
- wired (BSD, macOS): 被标记为始终保持在RAM中的内存。它从未移动到磁盘上。
使用和可用的总和不一定等于总数。在Windows上可用和免费是一样的。请参阅meminfo.py脚本,其中提供了如何将字节转换为人类可读形式的示例。
注
如果您只是想知道在跨平台方式中还剩下多少物理内存,那么只需依赖于可用字段即可。
>>> import psutil
>>> mem = psutil.virtual_memory()
>>> mem
svmem(total=10367352832, available=6472179712, percent=37.6, used=8186245120, free=2181107712, active=4748992512, inactive=2758115328, buffers=790724608, cached=3500347392, shared=787554304, slab=199348224)
>>>
>>> THRESHOLD = 100 * 1024 * 1024 # 100MB
>>> if mem.available <= THRESHOLD:
... print("warning")
...
>>>
meminfo.py脚本
#Print system memory information.
# python scripts/meminfo.py
import psutil
from psutil._common import bytes2human
def pprint_ntuple(nt):
for name in nt._fields:
value = getattr(nt, name)
if name != 'percent':
value = bytes2human(value)
print('%-10s : %7s' % (name.capitalize(), value))
def main():
print('MEMORY\n------')
pprint_ntuple(psutil.virtual_memory())
print('\nSWAP\n----')
pprint_ntuple(psutil.swap_memory())
if __name__ == '__main__':
main()
psutil.swap_memory
()
以命名元组的形式返回系统交换内存统计信息,包括以下字段:
- total:总交换内存(以字节为单位)
- used:使用交换内存(以字节为单位)
- free:空闲交换内存(以字节为单位)
- percent:使用百分比,计算公式为(total
- sin: 系统从磁盘交换进来的字节数(累计)
- sout: 系统从磁盘交换出的字节数(累计)
sin和sout在Windows上总是设置为0。请参阅meminfo.py脚本,其中提供了如何将字节转换为人类可读形式的示例。
>>> import psutil
>>> psutil.swap_memory()
sswap(total=2097147904L, used=886620160L, free=1210527744L, percent=42.3, sin=1050411008, sout=1906720768)
在5.2.3版中更改:在Linux上,这个函数依赖于/proc fs,而不是sysinfo()sysCall,因此它可以与psutil.PROCFS_PATH检索有关Linux容器的内存信息,例如Docker和Heroku。
硬盘
psutil.disk_partitions
(all=False)
以命名元组列表的形式返回所有已挂载的磁盘分区,包括设备、挂载点和文件系统类型,类似于UNIX上的“df”命令。如果all参数是假,它会尝试只区分和返回物理设备(例如,硬盘、光盘驱动器、U盘),而忽略其他所有设备(例如,内存分区,例如/dev/shm)。注意,这在所有系统上可能不是完全可靠的(例如,在BSD上这个参数被忽略)。名为tuple的fstype字段是一个根据平台而变化的字符串。在Linux上,它可以是/proc/filesystems(例如'ext3'为ext3硬盘驱动器或'iso9660'为CD-ROM驱动器)。在Windows上,它是通过GetDriveType确定的,可以是“可移动的”、“固定的”、“远程的”、“cdrom”、“未安装的”或“ramdisk”("removable", "fixed", "remote", "cdrom", "unmounted" or "ramdisk")。在macOS和BSD上,通过getfsstat syscall检索。查看disk_use .py脚本提供的示例用法。
>>> import psutil
>>> psutil.disk_partitions()
[sdiskpart(device='/dev/sda3', mountpoint='/', fstype='ext4', opts='rw,errors=remount-ro'),
sdiskpart(device='/dev/sda7', mountpoint='/home', fstype='ext4', opts='rw')]
psutil.disk_usage
(path)
返回包含指定路径的分区的磁盘使用情况统计信息,包括以字节表示的总空间、已使用空间和空闲空间,以及使用百分比。如果路径不存在,则会引发OSError。从Python 3.3开始,也可以使用shutil.disk_usage (见bpo - 12442)。查看disk_use .py脚本提供的示例用法。
>>> import psutil
>>> psutil.disk_usage('/')
sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
>>> psutil.disk_usage('D://lism//可视化//')
注
Unix通常为根用户保留5%的磁盘空间。total和used UNIX上的字段指的是总的总空间和使用的空间,而free表示可用于用户和percent表示用户利用情况(见源代码)。这就是为什么百分比价值看上去可能比你预期的要大5%。还请注意,这两个值都匹配“df”cmdline实用程序。
在4.3.0版本中更改:百分比值考虑根保留空间。
psutil
.disk_io_counters
(perdisk=False, nowrap=True)
以命名元组的形式返回系统范围内的磁盘I/O统计信息,包括以下字段:
- read_count:读次数
- write_count:写次数
- read_bytes:读取的字节数
- write_bytes:写入字节数
特定于平台的字段::
- read_time: (除NetBSD和OpenBSD)从磁盘读取的时间(以毫秒为单位)
- write_time: (除NetBSD和OpenBSD)写入磁盘所花费的时间(以毫秒为单位)
- busy_time: (linux, FreeBSD)用于实际I/O的时间(以毫秒为单位)
- read_merged_count (Linux):合并读取的次数(见iostats doc)
- write_merged_count (Linux):合并写入的次数(见iostats doc)
如果参数perdisk为真,则将系统上安装的每个物理磁盘作为字典返回相同的信息,其中分区名作为键,上面描述的命名元组作为值。有关示例应用程序,请参见ioto .py。在某些系统上,如Linux,在非常繁忙或长期存在的系统上,内核返回的数字可能溢出并换行(从零重新启动)。如果nowrap为真,psutil将通过函数调用检测和调整这些数字,并将“旧值”添加到“新值”中,以便返回的数字总是增加或保持不变,但从不减少。可以使用disk_io_tables .cache_clear()使nowrap缓存无效。在Windows上,可能不需要首先从cmd.exe发出diskperf -y命令来启用IO计数器。在无磁盘的机器上,如果perdisk为真,这个函数将返回None或{}。
>>> import psutil
>>> psutil.disk_io_counters()
sdiskio(read_count=8141, write_count=2431, read_bytes=290203, write_bytes=537676, read_time=5868, write_time=94922)
>>>
>>> psutil.disk_io_counters(perdisk=True)
{'sda1': sdiskio(read_count=920, write_count=1, read_bytes=2933248, write_bytes=512, read_time=6016, write_time=4),
'sda2': sdiskio(read_count=18707, write_count=8830, read_bytes=6060, write_bytes=3443, read_time=24585, write_time=1572),
'sdb1': sdiskio(read_count=161, write_count=0, read_bytes=786432, write_bytes=0, read_time=44, write_time=0)}
注
在Windows上"diskperf
-y"命令可能需要先执行,否则此函数将找不到任何磁盘。
版本5.3.0的变化:由于新的nowrap参数,数字不再在调用之间换行(从零重新启动)。
版本4.0.0版本中的变化:添加了busy_time (Linux, FreeBSD)、read_merged_count和write_merged_count (Linux)字段。
版本4.0.0版本中的变化:NetBSD不再有read_time和write_time字段。
网络
psutil.
net_io_counters
(pernic=False, nowrap=True)
作为命名元组返回系统范围内的网络I/O统计信息,包括以下属性:
- bytes_sent:发送的字节数
- bytes_recv:收到的字节数
- packets_sent:发送的数据包数
- packets_recv:收到的数据包数
- errin:收到错误的总数
- errout:发送时的错误总数
- dropin:丢弃的传入数据包总数
- dropout:被丢弃的传出数据包总数(在MacOS和BSD上总是为0)
如果pernic为真,则将系统上安装的每个网络接口作为字典返回相同的信息,其中网络接口名称作为键,上面描述的命名元组作为值。在某些系统上,如Linux,在非常繁忙或长期存在的系统上,内核返回的数字可能溢出并换行(从零重新启动)。如果nowrap为真,psutil将通过函数调用检测和调整这些数字,并将“旧值”添加到“新值”中,以便返回的数字总是增加或保持不变,但从不减少。cache_clear()可以用来使nowrap缓存失效。在没有网络迭代的机器上,如果pernic为真,这个函数将返回None或{}。
>>> import psutil
>>> psutil.net_io_counters()
snetio(bytes_sent=14508483, bytes_recv=62749361, packets_sent=84311, packets_recv=94888, errin=0, errout=0, dropin=0, dropout=0)
>>>
>>> psutil.net_io_counters(pernic=True)
{'lo': snetio(bytes_sent=547971, bytes_recv=547971, packets_sent=5075, packets_recv=5075, errin=0, errout=0, dropin=0, dropout=0),
'wlan0': snetio(bytes_sent=13921765, bytes_recv=62162574, packets_sent=79097, packets_recv=89648, errin=0, errout=0, dropin=0, dropout=0)}
亦见nettop.py和ifconfig.py用于示例应用程序。
在5.3.0版本中更改:由于新的,数字不再跨调用(从零重新启动)。
psutil.net_connections
(kind='inet')
返回系统范围内的套接字连接作为命名元组的列表。每个命名元组提供7个属性:
- fd:套接字文件描述符。如果连接引用当前进程,则可以将其传递给socket.fromfd以获得可用的socket对象。在Windows和SunOS中,这个值总是设置为-1。
- family: 地址族,可以是AF_INET、AF_INET6或AF_UNIX。
- type: 地址类型,可以是SOCK_STREAM、SOCK_DGRAM或SOCK_SEQPACKET。.
- laddr:本地地址作为一个(ip, port)命名的元组,或者AF_UNIX套接字的路径。有关UNIX套接字,请参阅下面的说明。
- raddr:在UNIX套接字的情况下,称为元组的(ip, port)远程地址或绝对路径。当远程端点没有连接时,您将得到一个空的元组 (AF_INET*)或“”(AF_UNIX)。有关UNIX套接字,请参阅下面的说明。
- status:表示TCP连接的状态。返回值是psutil.CONN_* constants (a string).。对于UDP和UNIX套接字,它总是psutil.CONN_NONE。
- pid:打开套接字的进程的PID,如果可检索,则为None。在某些平台上(例如Linux),该字段的可用性取决于进程特权(需要root)。
kind参数是一个字符串,用于过滤符合以下条件的连接:
类值 | 连接使用 |
"inet" | IPv 4和IPv 6 |
"inet4" | IPv 4 |
"inet6" | IPv 6 |
"tcp" | tcp |
"tcp4" | 基于IPv 4的TCP协议 |
"tcp6" | 基于IPv 6的TCP协议 |
"udp" | UDP |
"udp4" | UDP在IPv 4上的应用 |
"udp6" | UDP在IPv 6上的应用 |
"unix" | Unix套接字(UDP和TCP协议) |
"all" | 所有可能的家庭和协议的总和 |
在macOS和AIX上,这个函数需要根特权。要获得每个进程的连接,请使用Process.connections()。另外,请参阅netstat.py示例脚本。例子:
>>> import psutil
>>> psutil.net_connections()
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED', pid=1254),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING', pid=2987),
pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=60759), raddr=addr(ip='72.14.234.104', port=80), status='ESTABLISHED', pid=None),
pconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=51314), raddr=addr(ip='72.14.234.83', port=443), status='SYN_SENT', pid=None)
...]
注
(macOS和AIX) psutil.AccessDenied总是被抛出,除非作为根运行。这是操作系统和lsof的一个限制。。
(Solaris)不支持UNIX套接字。注
(Linux, FreeBSD) UNIX套接字的“raddr”字段总是设置为“”。这是操作系统的一个限制。
(OpenBSD) UNIX套接字的“laddr”和“raddr”字段总是设置为“”。这是操作系统的一个限制。
新版本2.1.0。
在5.3.0版本中改变::socket“fd”现在被设置为实数,而不是-1。
在5.3.0版本中更改::“laddr”和“raddr”被命名为元组。。
psutil.net_if_addrs
()
返回与系统上安装的每个NIC(网络接口卡)相关联的地址,作为一个字典,其键是NIC名称,值是分配给NIC的每个地址的命名元组列表。每个命名元组包含5个字段:
-
- family: 地址族,可以是 AF_INET或AF_INET6或psutil.AF_LINK,它指的是MAC地址。
- address: 主网卡地址(总是设置)。
- netmask: 网络掩码地址(可能没有)。
- broadcast: 广播地址(可能没有)。
- ptp: 表示“点对点”;它是点到点接口(通常是VPN)上的目标地址。广播和ptp是互斥的。可能没有。
例子:
>>> import psutil
>>> psutil.net_if_addrs()
{'lo': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast='127.0.0.1', ptp=None),
snicaddr(family=<AddressFamily.AF_INET6: 10>, address='::1', netmask='ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff', broadcast=None, ptp=None),
snicaddr(family=<AddressFamily.AF_LINK: 17>, address='00:00:00:00:00:00', netmask=None, broadcast='00:00:00:00:00:00', ptp=None)],
'wlan0': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.1.3', netmask='255.255.255.0', broadcast='192.168.1.255', ptp=None),
snicaddr(family=<AddressFamily.AF_INET6: 10>, address='fe80::c685:8ff:fe45:641%wlan0', netmask='ffff:ffff:ffff:ffff::', broadcast=None, ptp=None),
snicaddr(family=<AddressFamily.AF_LINK: 17>, address='c4:85:08:45:06:41', netmask=None, broadcast='ff:ff:ff:ff:ff:ff', ptp=None)]}
>>>
另见nettop.py和ifconfig.py用于示例应用程序。
注
如果你对其他地址族感兴趣(例如AF_BLUETOOTH),你可以使用更强大的netifaces扩展。。
可以有多个与每个接口关联的同一族的地址(这就是为什么dict值是列表的原因)。
广播和PTP在Windows上不支持,并且总是None.
新版本3.0.0。
在3.2.0版本中更改:PTP字段被添加。
在4.4.0版本中更改:增加对Windows的netmask字段的支持,在不再总是None.
psutil.net_if_stats
()
将安装在系统上的每个NIC(网络接口卡)的信息作为字典返回,该字典的密钥是NIC名称,值是具有以下字段的命名元组:
- isup: 一个bool,指示NIC是否已启动并正在运行。
- duplex: 双工通信类型;它可以是NIC_DUPLEX_FULL、NIC_DUPLEX_HALF或NIC_DUPLEX_UNKNOWN。
- speed: 网卡速度以兆比特(MB)表示,如果它不能被确定(如' localhost '),它将被设置为0。
- mtu: NIC的最大传输单元,以字节表示。
例子:
>>> import psutil
>>> psutil.net_if_stats()
{'eth0': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_FULL: 2>, speed=100, mtu=1500),
'lo': snicstats(isup=True, duplex=<NicDuplex.NIC_DUPLEX_UNKNOWN: 0>, speed=0, mtu=65536)}
亦见nettop.py和ifconfig.py用于示例应用程序。
新版本3.0.0。
感应器
psutil.sensors_temperatures
(fahrenheit=False)
返回硬件温度。每个条目都是一个表示特定硬件温度传感器的命名元组(它可能是CPU、硬盘或其他东西,这取决于操作系统及其配置)。除非fahrenheit(华氏温度)设置为真,否则所有温度都用摄氏温度表示。如果操作系统不支持传感器,则返回一个空dict。例子:
>>> import psutil
>>> psutil.sensors_temperatures()
{'acpitz': [shwtemp(label='', current=47.0, high=103.0, critical=103.0)],
'asus': [shwtemp(label='', current=47.0, high=None, critical=None)],
'coretemp': [shwtemp(label='Physical id 0', current=52.0, high=100.0, critical=100.0),
shwtemp(label='Core 0', current=45.0, high=100.0, critical=100.0),
shwtemp(label='Core 1', current=52.0, high=100.0, critical=100.0),
shwtemp(label='Core 2', current=45.0, high=100.0, critical=100.0),
shwtemp(label='Core 3', current=47.0, high=100.0, critical=100.0)]}
另见temperatures.py和sensors.py用于示例应用程序。
可用性:Linux,FreeBSD
新版本5.1.0。
在5.5.0版本中更改:增加FreeBSD支持
psutil.sensors_fans
()
返回硬件风扇速度。每个条目都是一个命名元组,表示某个硬件传感器风扇。风扇速度以RPM表示(每分钟回合数)。如果操作系统不支持传感器,则返回一个空dict。例子:
>>> import psutil
>>> psutil.sensors_fans()
{'asus': [sfan(label='cpu_fan', current=3200)]}
另见fans.py和sensors.py用于示例应用程序。
可用性:Linux,MacOS
新版本5.2.0。
psutil.sensors_battery
()
以命名元组的形式返回电池状态信息,包括以下值。如果没有电池安装或指标不能确定,没有返回。
- percent: 电池剩余电量的百分比。
- secsleft: 粗略估计电池电量耗尽前还剩多少秒。如果连接了交流电源,则将其设置为psutil.POWER_TIME_UNLIMITED。如果无法确定,则将其设置为psutil.POWER_TIME_UNKNOWN。.
- power_plugged: 如果连接了交流电源线,则为True;如果没有连接,则为False;如果无法确定,则为None。
例子:
>>> import psutil
>>>
>>> def secs2hours(secs):
... mm, ss = divmod(secs, 60)
... hh, mm = divmod(mm, 60)
... return "%d:%02d:%02d" % (hh, mm, ss)
...
>>> battery = psutil.sensors_battery()
>>> battery
sbattery(percent=93, secsleft=16628, power_plugged=False)
>>> print("charge = %s%%, time left = %s" % (battery.percent, secs2hours(battery.secsleft)))
charge = 93%, time left = 4:37:08
另见battery.py和sensors.py用于示例应用程序。
可用性:Linux、Windows、FreeBSD
新版本5.1.0。
在5.4.2版中更改:增加MacOS支持
其他系统信息
psutil.boot_time
()
返回系统启动时间(以秒为单位)。例子:
>>> import psutil, datetime
>>> psutil.boot_time()
1389563460.0
>>> datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
'2014-01-12 22:51:00'
注
在Windows上,如果跨不同进程使用此函数,则该函数可能返回1秒后的时间(请参见第1007期).
!!没看懂:
>>> import psutil, datetime
>>> datetime.datetime.now()
datetime.datetime(2019, 12, 26, 13, 48, 31, 251535)
>>> datetime.datetime.fromtimestamp(psutil.boot_time()).strftime("%Y-%m-%d %H:%M:%S")
'2019-12-11 08:27:05'
!? 2019-12-11 08:27:05这个时间是什么?
psutil.users
()
将当前连接到系统上的用户作为命名元组列表返回,包括以下字段:
- user: 用户的名称。
- terminal: 与用户关联的tty或伪tty(如果有的话),否则为None。
- host: 与条目关联的主机名(如果有的话)。
- started: 创建时间作为自纪元以来以秒为单位表示的浮点数。
- pid: 登录进程的pid(如sshd、tmux、gdm-session-worker等)。在Windows和OpenBSD中,这总是设置为None。
例子:
>>> import psutil
>>> psutil.users()
[suser(name='giampaolo', terminal='pts/2', host='localhost', started=1340737536.0, pid=1352),
suser(name='giampaolo', terminal='pts/3', host='localhost', started=1340737792.0, pid=1788)]
在5.3.0版本中更改:添加“PID”字段
进程
功能
psutil.pids
()
返回当前运行pid的排序列表。为了遍历所有进程并避免竞争条件,应该首选process_iter()。
>>> import psutil
>>> psutil.pids()
[1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, ..., 32498]
在5.6.0版本中更改:PIDS按排序顺序返回。
psutil.process_iter
(attrs=None, ad_value=None)
返回一个迭代器,为本地机器上所有正在运行的进程生成一个进程类实例。每个实例只创建一次,然后缓存到一个内部表中,在每次产生一个元素时更新这个表。缓存的进程实例将被检查身份,以便在另一个进程重用PID时确保安全,在这种情况下,缓存的实例将被更新。与psutil.pids()相比,这是遍历进程的首选方法。进程返回的排序顺序基于它们的PID。attrs和ad_value的含义与Process.as_dict()相同。如果指定了attrs,则在内部调用Process.as_dict(),并将结果dict存储为附加到返回的进程实例的info属性。如果attrs是一个空列表,它将检索所有进程信息(慢)。使用示例:
>>> import psutil
>>> for proc in psutil.process_iter():
... try:
... pinfo = proc.as_dict(attrs=['pid', 'name', 'username'])
... except psutil.NoSuchProcess:
... pass
... else:
... print(pinfo)
...
{'name': 'systemd', 'pid': 1, 'username': 'root'}
{'name': 'kthreadd', 'pid': 2, 'username': 'root'}
{'name': 'ksoftirqd/0', 'pid': 3, 'username': 'root'}
...
更紧凑的版本吸引人参数:
>>> import psutil
>>> for proc in psutil.process_iter(attrs=['pid', 'name', 'username']):
... print(proc.info)
...
{'name': 'systemd', 'pid': 1, 'username': 'root'}
{'name': 'kthreadd', 'pid': 2, 'username': 'root'}
{'name': 'ksoftirqd/0', 'pid': 3, 'username': 'root'}
...
创建一个{pid:
info,
...}数据结构:
>>> import psutil
>>> procs = {p.pid: p.info for p in psutil.process_iter(attrs=['name', 'username'])}
>>> procs
{1: {'name': 'systemd', 'username': 'root'},
2: {'name': 'kthreadd', 'username': 'root'},
3: {'name': 'ksoftirqd/0', 'username': 'root'},
...}
演示如何按名称筛选进程的示例:
>>> import psutil
>>> [p.info for p in psutil.process_iter(attrs=['pid', 'name']) if 'python' in p.info['name']]
[{'name': 'python3', 'pid': 21947},
{'name': 'python', 'pid': 23835}]
另见过程过滤获取更多示例。
在5.3.0版本中更改:添加“atts”和“ad_value”参数。
psutil.pid_exists
(PID)
检查给定的PID是否存在于当前进程列表中。这比在psutil.pids()中执行pid要快,应该是首选的方法。
psutil.wait_procs
(procs, timeout=None, callback=None)
等待进程实例列表终止的便利函数。返回一个(gone, alive)元组,表示哪些进程已经消失,哪些进程仍然是活动的。消失的那些将有一个新的returncode属性,指示进程退出状态(对于不是我们的子进程将为None)。callback是一个函数,当被等待的进程之一被终止,并且一个进程实例作为回调参数传递时,该函数被调用。这个函数将在所有进程终止或超时(秒)发生时立即返回。与Process.wait()不同,如果发生超时,它不会引发TimeoutExpired。一个典型的用例可能是:
- 将SIGTERM发送到进程列表
- 给他们一些时间结束
- 把SIGKILL发送给那些还活着
终止和等待此进程的所有子进程的示例:
import psutil
def on_terminate(proc):
print("process {} terminated with exit code {}".format(proc, proc.returncode))
procs = psutil.Process().children()
for p in procs:
p.terminate()
gone, alive = psutil.wait_procs(procs, timeout=3, callback=on_terminate)
for p in alive:
p.kill()
异常
class psutil.Error
基本异常类。所有其他异常都继承自这个异常。
class psutil.NoSuchProcess
(pid, name=None, msg=None)
当当前进程列表中没有找到具有给定pid的进程或某个进程不再存在时,由进程类方法引发。name是进程消失之前的名称,只有在前面调用process .name()时才会设置它。
class psutil.ZombieProcess
(pid, name=None, ppid=None, msg=None)
在UNIX上查询僵死进程(Windows没有僵死进程)时,进程类方法可能会引发此问题。取决于所调用的方法,操作系统是否能够成功地检索进程信息。注意:这是NoSuchProcess的一个子类,所以如果您对检索僵尸不感兴趣(例如,在使用process_iter()时),您可以忽略这个异常,只捕获NoSuchProcess。
新版本3.0.0。
class psutil.AccessDenied
(pid=None, name=None, msg=None)
当执行操作的权限被拒绝时,由进程类方法引发。“name”是进程的名称(可以是None)。
class psutil.TimeoutExpired
(seconds, pid=None, name=None, msg=None)
如果超时过期且进程仍然是活动的,则由process .wait()引发。。
进程类
class psutil.Process
(pid=None)
表示具有给定pid的操作系统进程。如果省略pid,则使用当前进程pid (os.getpid)。如果pid不存在,则引发NoSuchProcess。在Linux上,pid还可以引用线程ID (threads()方法返回的ID字段)。在访问该类的方法时,始终准备捕捉NoSuchProcess和拒绝访问异常。散列构建可以用于该类的实例,以便在一段时间内标识单个进程(散列由混合进程PID和创建时间决定)。因此,它也可以与set一起使用。
注
为了同时有效地获取关于进程的多个信息,请确保使用oneshot()上下文管理器或as_dict()实用程序方法。
这个类绑定到进程的方式是唯一通过它的PID实现的。这意味着,如果进程终止,操作系统重用它的PID,那么您可能会与另一个进程进行交互。只有以下方法可以预先检查进程标识(通过PID +创建时间):nice() (set)、ionice() (set)、cpu_affinity() (set)、rlimit() (set)、children()、parent()、parents()、suspend() resume()、send_signal()、terminate() kill()。为了防止所有其他方法出现这个问题,您可以在查询进程之前使用is_running(),或者在遍历所有进程时使用process_iter()。但是必须注意,除非您处理非常“旧的”(非活动的)进程实例,否则这几乎不会成为问题。
oneshot
()
实用程序上下文管理器,它大大加快了同时检索多个进程信息的速度。在内部,不同的进程信息(例如name(), ppid(), uids(), create_time(),…)可以通过使用相同的例程来获取,但是只返回一个值,而丢弃其他值。当使用这个上下文管理器时,内部例程执行一次(在下面的name()示例中),返回感兴趣的值,并缓存其他值。共享相同内部例程的后续调用将返回缓存的值。退出上下文管理器块时清除缓存。建议在每次检索关于进程的多个信息时使用此方法。如果你幸运的话,你会得到一个地狱般的加速。例子:
>>> import psutil
>>> p = psutil.Process()
>>> with p.oneshot():
... p.name() # execute internal routine once collecting multiple info
... p.cpu_times() # return cached value
... p.cpu_percent() # return cached value
... p.create_time() # return cached value
... p.ppid() # return cached value
... p.status() # return cached value
...
>>>
这里有一个方法列表,可以根据您所在的平台利用加速。在下表中,水平emtpy行表示哪些进程方法可以在内部有效地组合在一起。最后一列(speedup)显示了如果将所有方法一起调用可以获得的加速效果的近似值(最好的情况)。
Linux | Windows | macOS | BSD | SunOS | AIX |
|
| ||||
| |||||
| |||||
| |||||
|
|
| |||
| |||||
| |||||
| |||||
|
|
|
| ||
|
|
|
|
| |
|
|
|
|
| |
加速比:+2.6x | 加速比:+1.8x/+6.5x | 加速比:+1.9x | 加速比:+2.0x | 加速比:+1.3x | 加速比:+1.3x |
新版本5.0.0。
pid
过程PID。这是类的唯一(只读)属性。
ppid
()
进程父PID。在Windows中,返回值在第一次调用后缓存。不能在POSIX上使用,因为如果进程变成僵尸,ppid可能会改变。
name
()
进程名称。在Windows中,返回值在第一次调用后缓存。POSIX上没有,因为进程名可能会更改。参见如何按名称查找进程。
exe
()
进程作为绝对路径执行。在某些系统中,这也可能是一个空字符串。返回值在第一次调用后缓存。
>>> import psutil
>>> psutil.Process().exe()
'/usr/bin/python2.7'
cmdline
()
以字符串列表的形式调用此进程的命令行。返回值不会被缓存,因为进程的cmdline可能会改变。
>>> import psutil
>>> psutil.Process().cmdline()
['python', 'manage.py', 'runserver']
environ
()
将进程的环境变量作为dict。注意:这可能不会反映进程启动后所做的更改。
>>> import psutil
>>> psutil.Process().environ()
{'LC_NUMERIC': 'it_IT.UTF-8', 'QT_QPA_PLATFORMTHEME': 'appmenu-qt5', 'IM_CONFIG_PHASE': '1', 'XDG_GREETER_DATA_DIR': '/var/lib/lightdm-data/giampaolo', 'GNOME_DESKTOP_SESSION_ID': 'this-is-deprecated', 'XDG_CURRENT_DESKTOP': 'Unity', 'UPSTART_EVENTS': 'started starting', 'GNOME_KEYRING_PID': '', 'XDG_VTNR': '7', 'QT_IM_MODULE': 'ibus', 'LOGNAME': 'giampaolo', 'USER': 'giampaolo', 'PATH': '/home/giampaolo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/giampaolo/svn/sysconf/bin', 'LC_PAPER': 'it_IT.UTF-8', 'GNOME_KEYRING_CONTROL': '', 'GTK_IM_MODULE': 'ibus', 'DISPLAY': ':0', 'LANG': 'en_US.UTF-8', 'LESS_TERMCAP_se': '\x1b[0m', 'TERM': 'xterm-256color', 'SHELL': '/bin/bash', 'XDG_SESSION_PATH': '/org/freedesktop/DisplayManager/Session0', 'XAUTHORITY': '/home/giampaolo/.Xauthority', 'LANGUAGE': 'en_US', 'COMPIZ_CONFIG_PROFILE': 'ubuntu', 'LC_MONETARY': 'it_IT.UTF-8', 'QT_LINUX_ACCESSIBILITY_ALWAYS_ON': '1', 'LESS_TERMCAP_me': '\x1b[0m', 'LESS_TERMCAP_md': '\x1b[01;38;5;74m', 'LESS_TERMCAP_mb': '\x1b[01;31m', 'HISTSIZE': '100000', 'UPSTART_INSTANCE': '', 'CLUTTER_IM_MODULE': 'xim', 'WINDOWID': '58786407', 'EDITOR': 'vim', 'SESSIONTYPE': 'gnome-session', 'XMODIFIERS': '@im=ibus', 'GPG_AGENT_INFO': '/home/giampaolo/.gnupg/S.gpg-agent:0:1', 'HOME': '/home/giampaolo', 'HISTFILESIZE': '100000', 'QT4_IM_MODULE': 'xim', 'GTK2_MODULES': 'overlay-scrollbar', 'XDG_SESSION_DESKTOP': 'ubuntu', 'SHLVL': '1', 'XDG_RUNTIME_DIR': '/run/user/1000', 'INSTANCE': 'Unity', 'LC_ADDRESS': 'it_IT.UTF-8', 'SSH_AUTH_SOCK': '/run/user/1000/keyring/ssh', 'VTE_VERSION': '4205', 'GDMSESSION': 'ubuntu', 'MANDATORY_PATH': '/usr/share/gconf/ubuntu.mandatory.path', 'VISUAL': 'vim', 'DESKTOP_SESSION': 'ubuntu', 'QT_ACCESSIBILITY': '1', 'XDG_SEAT_PATH': '/org/freedesktop/DisplayManager/Seat0', 'LESSCLOSE': '/usr/bin/lesspipe %s %s', 'LESSOPEN': '| /usr/bin/lesspipe %s', 'XDG_SESSION_ID': 'c2', 'DBUS_SESSION_BUS_ADDRESS': 'unix:abstract=/tmp/dbus-9GAJpvnt8r', '_': '/usr/bin/python', 'DEFAULTS_PATH': '/usr/share/gconf/ubuntu.default.path', 'LC_IDENTIFICATION': 'it_IT.UTF-8', 'LESS_TERMCAP_ue': '\x1b[0m', 'UPSTART_SESSION': 'unix:abstract=/com/ubuntu/upstart-session/1000/1294', 'XDG_CONFIG_DIRS': '/etc/xdg/xdg-ubuntu:/usr/share/upstart/xdg:/etc/xdg', 'GTK_MODULES': 'gail:atk-bridge:unity-gtk-module', 'XDG_SESSION_TYPE': 'x11', 'PYTHONSTARTUP': '/home/giampaolo/.pythonstart', 'LC_NAME': 'it_IT.UTF-8', 'OLDPWD': '/home/giampaolo/svn/curio_giampaolo/tests', 'GDM_LANG': 'en_US', 'LC_TELEPHONE': 'it_IT.UTF-8', 'HISTCONTROL': 'ignoredups:erasedups', 'LC_MEASUREMENT': 'it_IT.UTF-8', 'PWD': '/home/giampaolo/svn/curio_giampaolo', 'JOB': 'gnome-session', 'LESS_TERMCAP_us': '\x1b[04;38;5;146m', 'UPSTART_JOB': 'unity-settings-daemon', 'LC_TIME': 'it_IT.UTF-8', 'LESS_TERMCAP_so': '\x1b[38;5;246m', 'PAGER': 'less', 'XDG_DATA_DIRS': '/usr/share/ubuntu:/usr/share/gnome:/usr/local/share/:/usr/share/:/var/lib/snapd/desktop', 'XDG_SEAT': 'seat0'}
可用性:Linux,MacOS,Windows,SunOS
新版本4.0.0。
在5.3.0版本中更改:增加SunOS支持
在5.6.3版中更改:新增AIX支持
create_time
()
进程的创建时间是一个浮点数,以秒为单位,从epoch开始,以UTC表示。返回值在第一次调用后缓存。
>>> import psutil, datetime
>>> p = psutil.Process()
>>> p.create_time()
1307289803.47
>>> datetime.datetime.fromtimestamp(p.create_time()).strftime("%Y-%m-%d %H:%M:%S")
'2011-03-05 18:03:52'
as_dict
(attrs=None, ad_value=None)
以字典形式检索多个进程信息的实用方法。如果指定了attrs,那么它必须是一个字符串列表,反映可用的Process类的属性名。这里有一个可能的字符串值列表:'cmdline', 'connections', 'cpu_affinity', 'cpu_num', 'cpu_percent', 'cpu_times', 'create_time', 'cwd', 'environ', 'exe', 'gids', 'io_counters', 'ionice', 'memory_full_info', 'memory_info', 'memory_maps', 'memory_percent', 'name', 'nice', 'num_ctx_switches', 'num_fds', 'num_handles', 'num_threads', 'open_files', 'pid', 'ppid', 'status', 'terminal', 'threads', 'uids', 'username'`.如果没有传递attrs参数,则假定所有公共只读属性。ad_value是在访问被拒绝或检索特定进程信息时引发ZombieProcess异常时分配给dict键的值。在内部,as_dict()使用oneshot()上下文管理器,因此不需要也使用它。
>>> import psutil
>>> p = psutil.Process()
>>> p.as_dict(attrs=['pid', 'name', 'username'])
{'username': 'giampaolo', 'pid': 12366, 'name': 'python'}
>>>
>>> # get a list of valid attrs names
>>> list(psutil.Process().as_dict().keys())
['status', 'cpu_num', 'num_ctx_switches', 'pid', 'memory_full_info', 'connections', 'cmdline', 'create_time', 'ionice', 'num_fds', 'memory_maps', 'cpu_percent', 'terminal', 'ppid', 'cwd', 'nice', 'username', 'cpu_times', 'io_counters', 'memory_info', 'threads', 'open_files', 'name', 'num_threads', 'exe', 'uids', 'gids', 'cpu_affinity', 'memory_percent', 'environ']
在3.0.0版本中更改::ad_value在引发ZombieProcess异常时也被使用,而不仅仅是被拒绝访问
在4.5.0版本中更改:由于使用了oneshot()上下文管理器,as_dict()要快得多。
parent
()
将父进程作为进程对象返回的实用方法,预先检查PID是否被重用。如果没有已知的父PID,则返回None。请参见ppid()和parent()方法。
parents
()
实用程序方法,该方法将此进程的父进程作为进程实例列表返回。如果没有已知的父类,则返回一个空列表。请参见ppid()和parent()方法。
新版本5.6.0。
status
()
当前进程状态为字符串。返回的字符串是一个psutil.STATUS_ *常量。
cwd
()
进程当前工作目录作为绝对路径。
在5.6.4版中更改:增加对NetBSD的支持
username
()
拥有该进程的用户的名称。在UNIX上,这是通过使用实际进程uid来计算的。
uids
()
此进程的真实、有效和保存的用户id为命名元组。它与os.getresuid相同,但是可以用于任何进程PID。
可用性:Unix
gids
()
此进程的真实、有效和保存的用户id为命名元组。它与os.getresuid相同,但是可以用于任何进程PID。
可用性:Unix
terminal
()
与此进程关联的终端(如果有的话), 否则为None。这类似于“tty”命令,但是可以用于任何进程PID。
可用性:Unix
nice
(value=None)
获取或设置进程niceness(优先级)。在UNIX上,这个数字通常是从-20到20。nice值越高,进程的优先级越低。
>>> import psutil
>>> p = psutil.Process()
>>> p.nice(10) # set
>>> p.nice() # get
10
>>>
从Python 3.3开始,这个功能也可以作为os.getpriority和os.setpriority(参见BPO-10784)。在Windows上,这是通过GetPriorityClass和SetPriorityClass Windows api实现的,value是反映MSDN文档的psutil.*_PRIORITY_CLASS常量之一。增Windows上进程优先级的示例:
>>> p.nice(psutil.HIGH_PRIORITY_CLASS)
ionice
(ioclass=None, value=None)
获取或设置进程I/O niceness(优先级)。如果没有提供参数,它就充当get,在Linux上返回一个(ioclass, value)元组,在Windows上返回一个ioclass整数。如果提供了ioclass,它将作为一个集合。在这种情况下,只能在Linux上指定一个附加值,以便进一步增加或减少I/O优先级。这是可能的与平台相关的ioclass值。
Linux(参见ioprio_get手册):
- IOPRIO_CLASS_RT:(高)每次进程首先访问磁盘。小心使用它,因为它会饿死整个系统。附加优先权水平可以指定,范围为0(最高)至7(最低)。
- IOPRIO_CLASS_BE:(正常)没有设置特定I/O优先级的任何进程的默认设置。附加优先权水平范围从0(最高)至7(最低)。
- IOPRIO_CLASS_IDLE:(低)当没有其他人需要磁盘时,获得I/O时间。无额外价值被接受了。
- IOPRIO_CLASS_NONE:在以前没有设置优先级时返回。
Windows:
- IOPRIO_HIGH:最高优先事项。
- IOPRIO_NORMAL:默认优先级。
- IOPRIO_LOW:低优先。
- IOPRIO_VERYLOW:最低优先次序。
下面是一个例子,说明如何根据您所处的平台设置最高的I/O优先级:
>>> import psutil
>>> p = psutil.Process()
>>> if psutil.LINUX:
... p.ionice(psutil.IOPRIO_CLASS_RT, value=7)
... else:
... p.ionice(psutil.IOPRIO_HIGH)
...
>>> p.ionice() # get
pionice(ioclass=<IOPriority.IOPRIO_CLASS_RT: 1>, value=7)
可用性:Linux,WindowsVista+
在5.6.2版中更改:Windows接受新的IOPRIO_*常数包括新的IOPRIO_HIGH.
rlimit
(resource, limits=None)
获取或设置进程资源限制(参见man prlimit)。资源是psutil.RLIMIT_*常量之一。极限是一个(soft, hard)元组。它与resource.getrlimit和resource.setrlimit相同,但可以用于任何进程PID,而不仅仅是os.getpid。对于get,返回值是一个(soft, hard)元组。每个值可以是整数或psutil.RLIMIT_*。
例子:
>>> import psutil
>>> p = psutil.Process()
>>> # process may open no more than 128 file descriptors
>>> p.rlimit(psutil.RLIMIT_NOFILE, (128, 128))
>>> # process may create files no bigger than 1024 bytes
>>> p.rlimit(psutil.RLIMIT_FSIZE, (1024, 1024))
>>> # get
>>> p.rlimit(psutil.RLIMIT_FSIZE)
(1024, 1024)
>>>
可用性:Linux
io_counters
()
以命名元组的形式返回进程I/O统计信息。对于linux,您可以参考/proc文件系统文档.
- read_count: 执行的读操作的数量(累计)。这是为了计算UNIX上与读相关的系统调用(如read()和pread())的数量。
- write_count执行的写操作的数量(累计的)。这是为了计算UNIX上与写相关的系统调用的数量,比如write()和pwrite()。
- read_bytes: 读取的字节数(累计)。BSD总是-1。
- write_bytes: 写入的字节数(累计)。BSD总是-1。
特定于Linux的:
- read_chars (Linux): 这个进程传递给read()和pread()系统调用(累积)的字节数。与read_bytes不同,它不关心实际的物理磁盘I/O是否发生。
- write_chars (Linux): 这个进程传递给write()和pwrite()系统调用(累积)的字节数。与write_bytes不同,它不关心实际的物理磁盘I/O是否发生。。
特定于Windows的:
- other_count (Windows): 除读写操作外执行的I/O操作的数量。
- other_bytes (Windows): 除读写操作之外的操作期间传输的字节数。
>>> import psutil
>>> p = psutil.Process()
>>> p.io_counters()
pio(read_count=454556, write_count=3456, read_bytes=110592, write_bytes=0, read_chars=769931, write_chars=203)
可用性:Linux、BSD、Windows、AIX
在5.2.0版本中更改:加read_chars和write_chars在linux上,添加other_count和other_bytes在Windows上。
num_ctx_switches
()
这个过程执行的自愿和非自愿上下文切换的数量(累计)。
在5.4.1版中更改:新增AIX支持
num_fds
()
此进程当前打开的文件描述符的数量(非累积)。
可用性:Unix
num_handles
()
此进程当前使用的句柄数(非累积)。
可用性:Windows
num_threads
()
此进程当前使用的线程数(非累积)。
threads
()
返回进程打开的线程,作为一列命名元组,包括线程id和线程CPU时间(用户/系统)。在OpenBSD上,此方法需要根特权。
cpu_times
()
返回表示累积进程时间的命名元组,以秒为单位(请参见解释)。这类似于os.times但可用于任何进程PID。
- user:在用户模式下花费的时间。
- system:在内核模式下花费的时间。
- children_user: 所有子进程的用户时间(在Windows和macOS上总是0)。
- system_user: 所有子进程的用户时间(在Windows和macOS上总是0)。
- iowait: (Linux) 等待阻塞I/O完成的时间。这个值被排除在用户和系统时间计数之外(因为CPU没有做任何工作)。
>>> import psutil
>>> p = psutil.Process()
>>> p.cpu_times()
pcputimes(user=0.03, system=0.67, children_user=0.0, children_system=0.0, iowait=0.08)
>>> sum(p.cpu_times()[:2]) # cumulative, excluding children and iowait
0.70
在4.1.0版本中更改:返回两个额外字段:子用户和儿童系统.
在5.6.4版中更改:加iowait在Linux上。
cpu_percent
(interval=None)
返回一个浮点数,该浮点数表示进程CPU利用率的百分比,对于在不同CPU上运行多个线程的进程,这个百分比也可以是> 100.0。当interval为> 0.0时,将进程时间与系统CPU在interval(阻塞)之前和之后经过的时间进行比较。当interval为0.0或None时,将进程时间与自上次调用以来经过的系统CPU时间进行比较,立即返回。这意味着第一次调用它将返回一个无意义的0.0值,您应该忽略它。在这种情况下,建议在两次调用之间至少间隔0.1秒的情况下再次调用此函数。例子:
>>> import psutil
>>> p = psutil.Process()
>>> # blocking
>>> p.cpu_percent(interval=1)
2.0
>>> # non-blocking (percentage since last call)
>>> p.cpu_percent(interval=None)
2.9
注
如果进程在不同的cpu核上运行多个线程,则返回的值可以大于100.0。
返回的值在所有可用的cpu之间不是均匀地分配的(与psutil.cpu_percent()不同)。这意味着在一个有两个逻辑CPU的系统上运行的繁忙循环进程将被报告为CPU利用率为100%,而不是50%。这样做是为了与top UNIX实用程序保持一致,同时也为了更容易地识别占用CPU资源的进程,这些进程与CPU的数量无关。必须注意的是,Windows上的taskmgr.exe的行为不是这样的(它会报告50%的使用量)。要模拟Windows taskmgr.exe行为,可以这样做:p.cpu_percent() / psutil.cpu_count()。.
警告
第一次使用Interval=调用此方法0.0或None它将返回一个毫无意义的0.0应该忽略的值。
cpu_affinity
(cpus=None)
获取或设置进程当前CPU关联。CPU关联性包括告诉操作系统只在一组有限的CPU上运行一个进程(在Linux cmdline上,通常使用taskset命令)。如果没有传递任何参数,它将以整数列表的形式返回当前的CPU关联。如果传递它,那么它必须是一个指定新cpu亲缘关系的整数列表。如果传递了一个空列表,则假定(并设置)所有合格的cpu。在某些系统(如Linux)上,这并不一定意味着list(range(psutil.cpu_count())中的所有可用逻辑cpu。
>>> import psutil
>>> psutil.cpu_count()
4
>>> p = psutil.Process()
>>> # get
>>> p.cpu_affinity()
[0, 1, 2, 3]
>>> # set; from now on, process will run on CPU #0 and #1 only
>>> p.cpu_affinity([0, 1])
>>> p.cpu_affinity()
[0, 1]
>>> # reset affinity against all eligible CPUs
>>> p.cpu_affinity([])
可用性:Linux、Windows、FreeBSD
在2.2.0版本中更改:增加了对FreeBSD的支持
在5.1.0版本中更改:可以传递空列表来设置对所有合格CPU的关联。
cpu_num
()
返回当前正在运行的CPU。返回的数字应该<= psutil.cpu_count()。在FreeBSD上,某些内核进程可能返回-1。它可以与psutil.cpu_percent(percpu=True)结合使用,观察跨多个cpu分布的系统工作负载,如cpu_distribution.py示例脚本所示。
可用性:Linux、FreeBSD、SunOS
新版本5.1.0。
memory_info
()
根据表示进程内存信息的平台,返回一个带有变量字段的命名元组。所有plaform上的“可移植”字段是rss和vms。所有数字都用字节表示。
Linux | macOS | BSD | Solaris | AIX | Windows |
rss | rss | rss | rss | rss | rss (alias for wset) |
vms | vms | vms | vms | vms | vms (alias for pagefile) |
shared | pfaults | text |
|
| num_page_faults |
text | pageins | data |
|
| peak_wset |
lib |
| stack |
|
| wset |
data |
|
|
|
| peak_paged_pool |
dirty |
|
|
|
| paged_pool |
|
|
|
|
| peak_nonpaged_pool |
|
|
|
|
| nonpaged_pool |
|
|
|
|
| pagefile |
|
|
|
|
| peak_pagefile |
|
|
|
|
| private |
- rss:称为“常驻集大小”,这是一个进程使用的非交换物理内存。在UNIX上,它与“top”的RES列匹配)。在Windows中,这是wset字段的别名,它匹配taskmgr.exe的“Mem Usage”列。
- vms:称“虚拟内存大小”,这是进程使用的虚拟内存总量。在UNIX上,它匹配“top”的VIRT列。在Windows中,这是pagefile字段的别名,它匹配taskmgr.exe的“Mem使用量”“VM大小”列。
- shared: (Linux):可能与其他进程共享的内存。这与“top”的SHR列相匹配)。
- text (Linux, BSD): 又名TRS(文本常驻集)用于可执行代码的内存量。这与“top”的代码列相匹配)。
- data (Linux, BSD): 又名DRS(数据常驻集)用于可执行代码之外的物理内存的总量。它匹配“top”的数据列)。
- lib (Linux): 共享库使用的内存。
- dirty (Linux): 脏页的数量。
- pfaults (macOS): 页面错误的数量。
- pageins (macOS): 实际页面数。
对于Windows字段的解释依赖于PROCESS_MEMORY_COUNTERS_EX结构文档。Linux上的示例:
>>> import psutil
>>> p = psutil.Process()
>>> p.memory_info()
pmem(rss=15491072, vms=84025344, shared=5206016, text=2555904, lib=0, data=9891840, dirty=0)
在4.0.0版本中更改:返回多个字段,而不仅仅是rss和vm。
memory_info_ex
()
同memory_info()(不建议使用)。
警告
在4.0.0版中被弃用;使用memory_info()。
memory_full_info
()
这个方法返回与memory_info()相同的信息,另外,在某些平台(Linux、macOS、Windows)上,还提供其他指标(USS、PSS和swap)。正如本文中详细解释的那样,附加的指标提供了“有效”进程内存消耗的更好表示(在USS的情况下)。它通过传递整个进程地址来实现这一点。因此,它通常需要比memory_info()更高的用户权限,并且速度要慢得多。在没有实现额外字段的平台上,这只会返回与memory_info()相同的指标。
- uss (Linux, macOS, Windows):也称为“唯一设置大小”,这是一个进程特有的内存,如果进程现在终止,它将被释放。
- pss (Linux):也称为“比例设置大小”,即与其他进程共享的内存量,其计算方式是在共享内存的进程之间平均分配。也就是说,如果一个进程本身有10MBS,并且与另一个进程共享10MBS,那么它的PSS将是15 MBS。
- swap (Linux):已交换到磁盘的内存量。
注
USS可能是确定进程实际使用多少内存的最有代表性的指标。它表示如果进程现在终止将释放的内存量。
Linux上的示例:
>>> import psutil
>>> p = psutil.Process()
>>> p.memory_full_info()
pfullmem(rss=10199040, vms=52133888, shared=3887104, text=2867200, lib=0, data=5967872, dirty=0, uss=6545408, pss=6872064, swap=0)
>>>
另见procsmem.py用于示例应用程序。
新版本4.0.0。
memory_percent
(memtype=“rss”)
将进程内存与整个物理系统内存进行比较,并计算进程内存使用率的百分比。memtype参数是一个字符串,它指示希望与哪种类型的进程内存进行比较。您可以选择memory_info()和memory_full_info()返回的命名元组字段名(默认为“rss”)。
在4.0.0版本中更改:加memtype参数。
memory_maps
(grouped=True)
以命名元组列表的形式返回进程的映射内存区域,其字段取决于平台。这个方法对于获得这里所解释的进程内存使用的详细表示(最重要的值是“私有”内存)非常有用。如果groups为真,则将具有相同路径的映射区域分组在一起,并对不同的内存字段求和。如果分组为False,则每个映射区域显示为单个实体,并且命名的元组还将包括映射区域的地址空间(addr)和权限集(perms)。有关示例应用程序,请参见pmap.py。
Linux | Windows | FreeBSD | Solaris |
rss | rss | rss | rss |
size |
| private | anonymous |
pss |
| ref_count | locked |
shared_clean |
| shadow_count |
|
shared_dirty |
|
|
|
private_clean |
|
|
|
private_dirty |
|
|
|
referenced |
|
|
|
anonymous |
|
|
|
swap |
|
|
>>> import psutil
>>> p = psutil.Process()
>>> p.memory_maps()
[pmmap_grouped(path='/lib/x8664-linux-gnu/libutil-2.15.so', rss=32768, size=2125824, pss=32768, shared_clean=0, shared_dirty=0, private_clean=20480, private_dirty=12288, referenced=32768, anonymous=12288, swap=0),
pmmap_grouped(path='/lib/x8664-linux-gnu/libc-2.15.so', rss=3821568, size=3842048, pss=3821568, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=3821568, referenced=3575808, anonymous=3821568, swap=0),
...]
可用性:Linux、Windows、FreeBSD、SunOS
在5.6.0版本中更改:由于macOS本身的问题而取消了macOS支持(参见问题#1291)
children
(recursive=False)
以进程实例列表的形式返回此进程的子进程。如果recursive为真,则返回所有父后代。假设A ==这个过程的伪代码示例:
A ─┐
│
├─ B (child) ─┐
│ └─ X (grandchild) ─┐
│ └─ Y (great grandchild)
├─ C (child)
└─ D (child)
>>> p.children()
B, C, D
>>> p.children(recursive=True)
B, X, Y, C, D
注意,在上面的例子中,如果进程X消失了,进程Y也不会返回,因为进程A的引用也消失了。这个概念在单元测试中得到了很好的总结.
open_files
()
返回由进程作为命名元组列表打开的常规文件,包括以下字段:
- path:绝对文件名。
- fd:文件描述符号;在Windows上,这总是-1.
仅Linux:
- position (Linux):文件(偏移)位置。
- mode (Linux):一个字符串,指示文件是如何打开的,类似于打开内建mode争论。可能的值是'r', 'w', 'a', 'r+'和'a+'...在二进制模式或文本模式打开的文件之间没有区别("b"或"t").
- flags (Linux):传递给底层的标志os.openC在文件打开时调用(例如:Oos.O_RDONLY, os.O_TRUNC(等)
>>> import psutil
>>> f = open('file.ext', 'w')
>>> p = psutil.Process()
>>> p.open_files()
[popenfile(path='/home/giampaolo/svn/psutil/file.ext', fd=3, position=0, mode='w', flags=32769)]
警告
在Windows上,由于底层WindowsAPI的一些限制,此方法不可靠,在检索某些文件句柄时可能挂起。为了解决这个问题,psutil为每个句柄生成一个线程,如果它在100 ms后没有响应,就会将其杀死。这意味着Windows上的此方法不能保证枚举所有常规文件句柄(请参见第597期)。此外,它将只列出C:\驱动器中的文件(请参见第1020期).
警告
在BSD上,由于内核错误,此方法可以返回空路径(“”)的文件,因此不可靠(请参见第595期).
在3.1.0版本中更改:不再挂在Windows上。
在4.1.0版本中更改:新的position, mode和flags Linux上的字段。
connections
(kind="inet")
以命名元组列表的形式返回进程打开的套接字连接。若要获得系统范围的连接,请使用psutil.net_connections()每个命名元组提供6个属性:
- fd:套接字文件描述符。这可以传递给socket.fromfd获得可用的套接字对象。在Windows、FreeBSD和SunOS上,这总是设置为-1.
- family:地址族AF_iNet, AF_INET 6或AF_UNIX.
- type:地址类型SOCK_STREAM, SOCK_DGRAM or SOCK_SEQPACKET
- laddr:本地地址(ip,
- raddr:远程地址作为(ip,
- status:表示TCP连接的状态。返回值是psutil.CONN_*常数。对于UDP和UNIX套接字,这将始终是psutil.CONN_NONE.
kind参数是一个字符串,用于过滤符合以下条件的连接:
类值 | 连接使用 |
"inet" | IPv 4和IPv 6 |
"inet4" | IPv 4 |
"inet6" | IPv 6 |
"tcp" | tcp |
"tcp4" | 基于IPv 4的TCP协议 |
"tcp6" | 基于IPv 6的TCP协议 |
"udp" | UDP |
"udp4" | UDP在IPv 4上的应用 |
"udp6" | UDP在IPv 6上的应用 |
"unix" | Unix套接字(UDP和TCP协议) |
"all" | 所有可能的家庭和协议的总和 |
例子:
>>> import psutil
>>> p = psutil.Process(1694)
>>> p.name()
'firefox'
>>> p.connections()
[pconn(fd=115, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=48776), raddr=addr(ip='93.186.135.91', port=80), status='ESTABLISHED'),
pconn(fd=117, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=43761), raddr=addr(ip='72.14.234.100', port=80), status='CLOSING'),
pconn(fd=119, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=60759), raddr=addr(ip='72.14.234.104', port=80), status='ESTABLISHED'),
pconn(fd=123, family=<AddressFamily.AF_INET: 2>, type=<SocketType.SOCK_STREAM: 1>, laddr=addr(ip='10.0.0.1', port=51314), raddr=addr(ip='72.14.234.83', port=443), status='SYN_SENT')]
注
(Solaris)不支持UNIX套接字。
(Linux,FreeBSD)UNIX套接字的“raddr”字段总是设置为“”。这是操作系统的一个限制。
(OpenBSD)UNIX套接字的“LADR”和“raddr”字段总是设置为“”。这是操作系统的一个限制。
(AIX)psutil.AccessDenied始终引发,除非以根用户身份运行(lsof也会这样做)。
在5.3.0版本中更改:“LADIR”和“raddr”是命名为元组的。
is_running
()
返回当前进程是否在当前进程列表中运行。这也是可靠的,如果进程已经消失,并且它的PID被另一个进程重用,因此它必须被优先于执行。psutil.pid_exists(p.pid).
注
这个会回来的True同样,如果进程是僵尸(p.status()
==
psutil.STATUS_ZOMBIE).
send_signal
(signal)
发送一个信号给进程(参见信号模块常量),预先检查PID是否被重用。在UNIX上,这与os.kill(pid, sig)相同。在仅限Windows的SIGTERM上,支持CTRL_C_EVENT和CTRL_BREAK_EVENT信号,并将SIGTERM视为kill()的别名。请参见如何杀死进程树并终止子进程。
在3.2.0版本中更改:在Windows上添加了对CTRL_C_EventandCTRL_BRACK_EventSignal的支持。
suspend
()
使用SIGSTOP信号暂停进程执行,预先检查PID是否被重用。在UNIX上,这与os.kill(pid, signal.SIGSTOP)相同。在Windows上,这是通过挂起所有进程线程执行来完成的。
resume
()
使用SIGCONT信号提前恢复进程执行,检查PID是否被重用。在UNIX上,这与os.kill(pid, signal.SIGCONT)相同。在Windows上,这是通过恢复所有进程线程执行来完成的。
terminate
()
使用SIGTERM信号提前终止进程,检查PID是否被重用。在UNIX上,这与os.kill(pid, signal.SIGTERM)相同。在Windows中,这是kill()的别名。请参见如何杀死进程树并终止子进程。
kill
()
通过使用SIGKILL信号预先检查PID是否被重用来终止当前进程。在UNIX上,这与os.kill(pid, signal.SIGKILL)相同。在Windows上,这是通过使用TerminateProcess完成的。请参见如何杀死进程树并终止子进程。.
wait
(timeout=None)
等待进程终止,如果进程是当前进程的子进程,也返回退出码,否则不返回。在Windows上没有这样的限制(总是返回退出码)。如果进程已经终止,则立即返回None,而不是引发NoSuchProcess。超时以秒为单位。如果指定并且进程仍然是活动的,则抛出TimeoutExpired异常。timeout=0可用于非阻塞应用程序:它将立即返回或引发TimeoutExpired。要等待多个进程,可以使用psutil.wait_procs()。
>>> import psutil
>>> p = psutil.Process(9891)
>>> p.terminate()
>>> p.wait()
Popen类
class psutil.Popen
(*args, **kwargs)
一个更方便的stdlib接口subprocess.Popen...它启动一个子进程,而您处理它的方式与使用subprocess.Popen...但除此之外,它还提供了psutil.Processclass 。对于两个类共有的方法名称,如send_signal(), terminate()和kill() psutil.Process实现优先。要获得完整的文档,请参阅子进程模块文档。一个更方便的stdlib subprocess.Popen接口。它启动一个子进程,您可以像使用subprocess.Popen一样处理它。此外,它还提供了psutil.Process类的所有方法。对于两个类都通用的方法名,如send_signal()、terminate()和kill() psutil.Process实现优先。有关完整的文档,请参阅子流程模块文档。
注
与subprocess.Popen不同的是,这个类预先检查PID是否在send_signal()、terminate()和kill()上重用,这样就不会意外地终止另一个进程,从而修复了BPO-6973。
>>> import psutil
>>> from subprocess import PIPE
>>>
>>> p = psutil.Popen(["/usr/bin/python", "-c", "print('hello')"], stdout=PIPE)
>>> p.name()
'python'
>>> p.username()
'giampaolo'
>>> p.communicate()
('hello\n', None)
>>> p.wait(timeout=2)
0
>>>
psutil.Popen对象通过WITH语句作为上下文管理器得到支持:退出时,标准文件描述符被关闭,进程等待。所有Python版本都支持这一点。
>>> import psutil, subprocess
>>> with psutil.Popen(["ifconfig"], stdout=subprocess.PIPE) as proc:
>>> log.write(proc.stdout.read())
在4.4.0版本中更改:添加上下文管理器支持
Windows服务
psutil.win_service_iter
()
返回一个迭代器,生成一个WindowsService已安装的所有Windows服务的类实例。
新版本4.2.0。
可用性:Windows
!!>>> for var in list(psutil.win_service_iter()):
... print(var)
...
psutil.win_service_get
(name)
按名称获取Windows服务,返回WindowsService举个例子。提高psutil.NoSuchProcess如果不存在具有此名称的服务。
新版本4.2.0。
可用性:Windows
class psutil.WindowsService
表示具有给定名称的Windows服务。这个类由win_service_iter()和win_service_get()函数返回,它不应该被直接实例化。
name
()
服务名称。该字符串是引用服务的方式,可以将其传递给win_service_get()以获得新的WindowsService实例。
display_name
()
服务显示名称。实例化该类时缓存该值。
binpath
()
服务二进制/exe文件的完全限定路径为字符串,包括命令行参数。
username
()
拥有此服务的用户的名称。
start_type
()
可以是“automatic”, “manual” or “disabled”.
pid
()
进程PID(如果有的话) ,否则为None。这可以传递给进程类来控制服务的进程。
status
()
服务状态为字符串,可以是“running”, “paused”, “start_pending”, “pause_pending”, “continue_pending”, “stop_pending” or “stopped”.( pending 等待)
description
()
服务长描述。
as_dict
()
以字典的形式检索上述所有信息的实用程序方法。
新版本4.2.0。
可用性:Windows
示例代码:
>>> import psutil
>>> list(psutil.win_service_iter())
[<WindowsService(name='AeLookupSvc', display_name='Application Experience') at 38850096>,
<WindowsService(name='ALG', display_name='Application Layer Gateway Service') at 38850128>,
<WindowsService(name='APNMCP', display_name='Ask Update Service') at 38850160>,
<WindowsService(name='AppIDSvc', display_name='Application Identity') at 38850192>,
...]
>>> s = psutil.win_service_get('alg')
>>> s.as_dict()
{'binpath': 'C:\\Windows\\System32\\alg.exe',
'description': 'Provides support for 3rd party protocol plug-ins for Internet Connection Sharing',
'display_name': 'Application Layer Gateway Service',
'name': 'alg',
'pid': None,
'start_type': 'manual',
'status': 'stopped',
'username': 'NT AUTHORITY\\LocalService'}
常数
操作系统常数
psutil.POSIX
psutil.LINUX
psutil.WINDOWS
psutil.MACOS
psutil.FREEBSD
psutil.NETBSD
psutil.OPENBSD
psutil.BSD
psutil.SUNOS
psutil.AIX
bool常量,它定义了您所在的平台。例如,如果在Windows上,Windows常量为真,其他所有常量为假。
新版本4.0.0。
在5.4.0版本中更改:新增AIX
psutil.OSX
别名MACOS.
警告
在5.4.7版中被弃用;使用MACOS。
psutil.PROCFS_PATH
Linux、Solaris和AIX上/proc文件系统的路径(默认为"/proc")。您可能希望在导入psutil之后立即重新设置这个常量,以防您的/proc文件系统安装在其他地方,或者如果您想检索有关linux容器的信息,如Docker、Heroku或LXC(请参阅这里获取更多信息)。必须指出,此技巧仅适用于依赖/proc文件系统的API(例如,记忆API和大多数Process类方法)。
可用性:Linux、Solaris、AIX
新版本3.2.3。
在3.4.2版中更改:也可在Solaris上使用。
在5.4.0版本中更改:也可以在AIX上使用。
过程状态常数
psutil.STATUS_RUNNING
psutil.STATUS_SLEEPING
psutil.STATUS_DISK_SLEEP
psutil.STATUS_STOPPED
psutil.STATUS_TRACING_STOP
psutil.STATUS_ZOMBIE
psutil.STATUS_DEAD
psutil.STATUS_WAKE_KILL
psutil.STATUS_WAKING
psutil.STATUS_PARKED
(linux)
psutil.STATUS_IDLE
(linux, MacOS, FreeBSD)
psutil.STATUS_LOCKED
(FreeBSD)
psutil.STATUS_WAITING
(FreeBSD)
psutil.STATUS_SUSPENDED
(NetBSD)
表示进程状态。返回psutil.Process.status().
新版本3.4.1:STATUS_SUSPENDED(NetBSD)
新版本5.4.7:STATUS_PARKED(Linux)
进程优先级常数
psutil.REALTIME_PRIORITY_CLASS
psutil.HIGH_PRIORITY_CLASS
psutil.ABOVE_NORMAL_PRIORITY_CLASS
psutil.NORMAL_PRIORITY_CLASS
psutil.IDLE_PRIORITY_CLASS
psutil.BELOW_NORMAL_PRIORITY_CLASS
表示Windows上进程的优先级(参见SetPriorityClass)。它们可以与psutil.Process.nice()获取或设置进程优先级。
可用性:Windows
psutil.IOPRIO_CLASS_NONE
psutil.IOPRIO_CLASS_RT
psutil.IOPRIO_CLASS_BE
psutil.IOPRIO_CLASS_IDLE
一组整数,表示Linux上进程的I/O优先级。它们可以与psutil.Process.ionice()一起使用,以获得或设置进程I/O优先级。IOPRIO_CLASS_NONE和IOPRIO_CLASS_BE (best effort)是没有设置特定I/O优先级的进程的默认值。IOPRIO_CLASS_RT (real time)意味着不管系统中发生了什么,进程都将首先访问磁盘。IOPRIO_CLASS_IDLE表示当没有其他人需要磁盘时,进程将获得I/O时间。更多信息请参阅ionice命令行实用工具手册或ioprio_get系统调用手册。
可用性:Linux
psutil.IOPRIO_VERYLOW
psutil.IOPRIO_LOW
psutil.IOPRIO_NORMAL
psutil.IOPRIO_HIGH
表示Windows上进程的I/O优先级的一组整数。它们可以与psutil.Process.ionice()获取或设置进程I/O优先级。
可用性:Windows
新版本5.6.2。
过程资源常数
psutil.RLIM_INFINITY
psutil.RLIMIT_AS
psutil.RLIMIT_CORE
psutil.RLIMIT_CPU
psutil.RLIMIT_DATA
psutil.RLIMIT_FSIZE
psutil.RLIMIT_LOCKS
psutil.RLIMIT_MEMLOCK
psutil.RLIMIT_MSGQUEUE
psutil.RLIMIT_NICE
psutil.RLIMIT_NOFILE
psutil.RLIMIT_NPROC
psutil.RLIMIT_RSS
psutil.RLIMIT_RTPRIO
psutil.RLIMIT_RTTIME
psutil.RLIMIT_SIGPENDING
psutil.RLIMIT_STACK
用于获取和设置与psutil.Process.rlimit()一起使用的进程资源限制的常量。有关更多信息,请参见man prlimit。
可用性:Linux
连接常数
psutil.CONN_ESTABLISHED
psutil.CONN_SYN_SENT
psutil.CONN_SYN_RECV
psutil.CONN_FIN_WAIT1
psutil.CONN_FIN_WAIT2
psutil.CONN_TIME_WAIT
psutil.CONN_CLOSE
psutil.CONN_CLOSE_WAIT
psutil.CONN_LAST_ACK
psutil.CONN_LISTEN
psutil.CONN_CLOSING
psutil.CONN_NONE
psutil.CONN_DELETE_TCB
(Windows)
psutil.CONN_IDLE
(Solaris)
psutil.CONN_BOUND
(Solaris)
一组表示TCP连接状态的字符串。由psutil.Process.connections()和psutil.net_connections()(状态字段)返回。
硬件常数
psutil.AF_LINK
常量,用于标识与网络接口关联的MAC地址。与psutil.net_if_addrs()一起使用
新版本3.0.0。
psutil.NIC_DUPLEX_FULL
psutil.NIC_DUPLEX_HALF
psutil.NIC_DUPLEX_UNKNOWN
确定网卡(网络接口卡)是否具有全模式或半模式速度的常量。NIC_DUPLEX_FULL表示NIC可以同时发送和接收数据(文件),NIC_DUPLEX_FULL表示NIC可以一次发送或接收数据。与psutil.net_if_stats()一起使用。.
新版本3.0.0。
psutil.POWER_TIME_UNKNOWN
psutil.POWER_TIME_UNLIMITED
电池的剩余时间是不能确定的还是无限的。可以分配给psutil.sensors_battery()的secsleft字段。
新版本5.1.0。
psutil.version_info
一个元组来检查psutil安装的版本。例子:
>>> import psutil
>>> if psutil.version_info >= (4, 5):
... pass
Unicode
从5.3.0版本开始,psutil添加了对unicode的支持,参见问题#1040。下面的说明适用于任何返回字符串的API,如Process.exe()或Process.cwd(),包括与文件系统无关的方法,如Process.username()或WindowsService.description():
- 所有字符串都使用OS文件系统编码(sys.getfilesystemencoding())进行编码,该编码根据平台的不同而不同(例如macOS上的“UTF-8”,Win上的“mbcs”)
- 没有API调用应该崩溃与UnicodeDecodeError
- 相反,如果操作系统返回的数据编码错误,则使用以下错误处理程序替换字符串中的损坏字符:
- Python 3:sys.getfilesystemencodeerrors() (PY 3.6+)或“surrogatescape”在POSIX上,“replace”在Windows上
- Python 2:“replace”
- 在Python 2上,所有的api都返回字节(str类型),从不返回unicode
- 在Python 2上,你可以通过以下操作回到unicode:
>>> unicode(p.exe(), sys.getdefaultencoding(), errors="replace")
一个过滤进程的例子,有一个时髦的名字与Python 2和3一起工作:
# -*- coding: utf-8 -*-
import psutil, sys
PY3 = sys.version_info[0] == 2
LOOKFOR = u"ƒőő"
for proc in psutil.process_iter(attrs=['name']):
name = proc.info['name']
if not PY3:
name = unicode(name, sys.getdefaultencoding(), errors="replace")
if LOOKFOR == name:
print("process %s found" % p)
菜谱
按名称查找进程
检查字符串Process.name():
import psutil
def find_procs_by_name(name):
"Return a list of processes matching 'name'."
ls = []
for p in psutil.process_iter(attrs=['name']):
if p.info['name'] == name:
ls.append(p)
return ls
更高级一点,检查字符串Process.name(), Process.exe()和Process.cmdline():
import os
import psutil
def find_procs_by_name(name):
"Return a list of processes matching 'name'."
ls = []
for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
if name == p.info['name'] or \
p.info['exe'] and os.path.basename(p.info['exe']) == name or \
p.info['cmdline'] and p.info['cmdline'][0] == name:
ls.append(p)
return ls
杀进程树
import os
import signal
import psutil
def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
"on_terminate", if specified, is a callabck function which is
called as soon as a child terminates.
"""
assert pid != os.getpid(), "won't kill myself"
parent = psutil.Process(pid)
children = parent.children(recursive=True)
if include_parent:
children.append(parent)
for p in children:
p.send_signal(sig)
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)
终止子进程
当子进程启动时,这在单元测试中可能很有用。这将有助于确保没有额外的子进程(僵尸)留下来占用资源。
import psutil
def reap_children(timeout=3):
"Tries hard to terminate and ultimately kill all the children of this process."
def on_terminate(proc):
print("process {} terminated with exit code {}".format(proc, proc.returncode))
procs = psutil.Process().children()
# send SIGTERM
for p in procs:
try:
p.terminate()
except psutil.NoSuchProcess:
pass
gone, alive = psutil.wait_procs(procs, timeout=timeout, callback=on_terminate)
if alive:
# send SIGKILL
for p in alive:
print("process {} survived SIGTERM; trying SIGKILL".format(p))
try:
p.kill()
except psutil.NoSuchProcess:
pass
gone, alive = psutil.wait_procs(alive, timeout=timeout, callback=on_terminate)
if alive:
# give up
for p in alive:
print("process {} survived SIGKILL; giving up".format(p))
过滤和排序过程
这是一组一行程序,展示了如何使用process_iter()以便筛选进程并对它们进行排序。
设置:
>>> import psutil
>>> from pprint import pprint as pp
在其名称中具有“python”的进程:
>>> pp([p.info for p in psutil.process_iter(attrs=['pid', 'name']) if 'python' in p.info['name']])
[{'name': 'python3', 'pid': 21947},
{'name': 'python', 'pid': 23835}]
用户拥有的进程:
>>> import getpass
>>> pp([(p.pid, p.info['name']) for p in psutil.process_iter(attrs=['name', 'username']) if p.info['username'] == getpass.getuser()])
(16832, 'bash'),
(19772, 'ssh'),
(20492, 'python')]
正在积极运行的进程:
>>> pp([(p.pid, p.info) for p in psutil.process_iter(attrs=['name', 'status']) if p.info['status'] == psutil.STATUS_RUNNING])
[(1150, {'name': 'Xorg', 'status': 'running'}),
(1776, {'name': 'unity-panel-service', 'status': 'running'}),
(20492, {'name': 'python', 'status': 'running'})]
使用日志文件的进程:
>>> import os
>>> import psutil
>>> 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))
...
1510 upstart /home/giampaolo/.cache/upstart/unity-settings-daemon.log
2174 nautilus /home/giampaolo/.local/share/gvfs-metadata/home-ce08efac.log
2650 chrome /home/giampaolo/.config/google-chrome/Default/data_reduction_proxy_leveldb/000003.log
占用500M以上内存的进程:
>>> pp([(p.pid, p.info['name'], p.info['memory_info'].rss) for p in psutil.process_iter(attrs=['name', 'memory_info']) if p.info['memory_info'].rss > 500 * 1024 * 1024])
[(2650, 'chrome', 532324352),
(3038, 'chrome', 1120088064),
(21915, 'sublime_text', 615407616)]
内存消耗最多的三个进程:
>>> pp([(p.pid, p.info) for p in sorted(psutil.process_iter(attrs=['name', 'memory_percent']), key=lambda p: p.info['memory_percent'])][-3:])
[(21915, {'memory_percent': 3.6815453247662737, 'name': 'sublime_text'}),
(3038, {'memory_percent': 6.732935429979187, 'name': 'chrome'}),
(3249, {'memory_percent': 8.994554843376399, 'name': 'chrome'})]
消耗最多CPU时间的前三个进程:
>>> pp([(p.pid, p.info['name'], sum(p.info['cpu_times'])) for p in sorted(psutil.process_iter(attrs=['name', 'cpu_times']), key=lambda p: sum(p.info['cpu_times'][:2]))][-3:])
[(2721, 'chrome', 10219.73),
(1150, 'Xorg', 11116.989999999998),
(2650, 'chrome', 18451.97)]
导致I/O最多的三个进程:
>>> 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:])
[(21915, 'sublime_text'),
(1871, 'pulseaudio'),
(1510, 'upstart')]
打开更多文件描述符的前3个进程:
>>> pp([(p.pid, p.info) for p in sorted(psutil.process_iter(attrs=['name', 'num_fds']), key=lambda p: p.info['num_fds'])][-3:])
[(21915, {'name': 'sublime_text', 'num_fds': 105}),
(2721, {'name': 'chrome', 'num_fds': 185}),
(2650, {'name': 'chrome', 'num_fds': 354})]
字节转换
import psutil
def bytes2human(n):
# http://code.activestate.com/recipes/578019
# >>> bytes2human(10000)
# '9.8K'
# >>> bytes2human(100001221)
# '95.4M'
symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
prefix = {}
for i, s in enumerate(symbols):
prefix[s] = 1 << (i + 1) * 10
for s in reversed(symbols):
if n >= prefix[s]:
value = float(n) / prefix[s]
return '%.1f%s' % (value, s)
return "%sB" % n
total = psutil.disk_usage('/').total
print(total)
print(bytes2human(total))
…打印结果:
100399730688
93.5G
支撑平台
下面是开发和测试的平台:
- Linux Ubuntu 16.04
- MacOS 10.11 El Captain
- Windows 10
- Solaris 10
- FreeBSD 11
- OpenBSD 6.4
- NetBSD 8.0
- AIX 6.1 TL8 (maintainer Arnon Yaari)
较早的版本应该可以工作,但没有经过测试。对于Linux、Windows和MacOS,我们有continuos集成。其他平台有时需要手动测试。支持的最老的Windows版本是Windows XP,可以从源代码编译。最早支持Windows XP的是psutil 2.1.3。支持的Python版本有3.4+、2.7和2.6。
常见问题
- 问:我为什么要AccessDenied对于特定的过程?
- 答:当您查询另一个用户拥有的进程时,特别是在macOS(参见问题#883)和Windows上,可能会发生这种情况。不幸的是,除了以更高的权限运行Python进程外,您对此无能为力。在Unix上,您可以作为根用户运行Python进程,或者使用SUID位(这是ps和netstat等工具使用的技巧)。在Windows上,您可以作为NT AUTHORITY\SYSTEM运行Python进程,或者将Python脚本安装为Windows服务(这是ProcessHacker等工具使用的技巧)。