最近平台运行,出现一些问题,考虑如何设置监控。发现一个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上增加了interruptdpc字段。

psutil.cpu_percent(interval=Nonepercpu=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.0None它将返回一个毫无意义的0.0应该忽略的值。

psutil.cpu_times_percent(interval=Nonepercpu=False)

与cpu_percent()相同,但是提供了psutil.cpu_times(percpu=True)返回的每个特定CPU时间的利用率百分比。interval和percpu参数的含义与cpu_percent()相同。在Linux上,“guest”和“guest_nice”的百分比不会出现在“user”和“user_nice”的百分比中。

警告

第一次调用此函数时,间隔 = 0.0None它将返回一个毫无意义的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 - available) / total * 100
  • 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: (除NetBSDOpenBSD)从磁盘读取的时间(以毫秒为单位)
  • write_time: (除NetBSDOpenBSD)写入磁盘所花费的时间(以毫秒为单位)
  • busy_time:  (linuxFreeBSD)用于实际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_countwrite_merged_count (Linux)字段。

版本4.0.0版本中的变化:NetBSD不再有read_timewrite_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版本中改变::socketfd”现在被设置为实数,而不是-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

cpu_num()

cpu_percent()

cpu_percent()

cpu_num()

name()

name()

cpu_percent()

cpu_times()

cpu_times()

cpu_percent()

cmdline()

cmdline()

cpu_times()

io_counters()

memory_info()

cpu_times()

create_time()

create_time()

create_time()

memory_info()

memory_percent()

create_time()

name()

memory_maps()

num_ctx_switches()

gids()

memory_info()

memory_info()

ppid()

num_ctx_switches()

num_threads()

io_counters()

memory_percent()

memory_percent()

status()

num_handles()

name()

num_threads()

num_threads()

terminal()

num_threads()

create_time()

memory_info()

ppid()

ppid()

username()

gids()

memory_percent()

status()

status()

gids()

name()

num_ctx_switches()

terminal()

terminal()

num_ctx_switches()

ppid()

ppid()

num_threads()

status()

status()

gids()

gids()

uids()

terminal()

terminal()

uids()

uids()

username()

uids()

uids()

username()

username()

username()

username()

memory_full_info()

memory_maps()

加速比:+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_charswrite_chars在linux上,添加other_countother_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.0None它将返回一个毫无意义的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版本中更改:新的positionmodeflags 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, port)命名元组或path如果是AF_UNIX套接字。有关UNIX套接字,请参见下面的说明。
  • raddr:远程地址作为(ip, port)命名元组或绝对path在UNIX套接字的情况下。当远程端点未连接时,您将得到一个空元组(AF_INET*)或""(AF_UNIX)。有关UNIX套接字,请参见下面的说明。
  • 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(linuxMacOSFreeBSD)

psutil.STATUS_LOCKED(FreeBSD)

psutil.STATUS_WAITING(FreeBSD)

psutil.STATUS_SUSPENDED(NetBSD)

表示进程状态。返回psutil.Process.status().

新版本3.4.1STATUS_SUSPENDED(NetBSD)

新版本5.4.7STATUS_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等工具使用的技巧)。

用于Python中的进程和系统监视的跨平台库psutil相关推荐

  1. python 超参数_完整介绍用于Python中自动超参数调剂的贝叶斯优化

    完整介绍用于Python中自动超参数调剂的贝叶斯优化-1.jpg (109.5 KB, 下载次数: 0) 2018-7-4 23:45 上传 调剂机器学习超参数是一项繁琐但至关重要的任务,因为算法的性 ...

  2. python中的进程池:multiprocessing.Pool()

    python中的进程池: 我们可以写出自己希望进程帮助我们完成的任务,然后把任务批量交给进程池 进程池帮助我们创建进程完成任务,不需要我们管理. 进程池:利用multiprocessing 下的Poo ...

  3. Python中无法使用“~”获取Ubuntu系统的用户目录

    经测试后发现:Python中无法使用"~"获取Ubuntu系统的用户目录, 测试代码如下: if os.path.isdir("~"):print(" ...

  4. 在Python中对子进程进行非阻塞读取

    我正在使用子流程模块来启动子流程并连接到其输出流(stdout). 我希望能够在其stdout上执行非阻塞读取. 有没有一种方法可以使.readline成为非阻塞状态,或者在调用.readline之前 ...

  5. 深入理解Python中的进程

    博客核心内容: 进程的概念 并行与并发的区别 同步与异步的概念 进程创建的方式 父进程和子进程的关系 线程的相关概念 Python中进程池的相关概念 Python的的回调函数 进程池+回调函数的实际应 ...

  6. Python 中的进程、线程、协程、同步、异步、回调(一)

    在进一步之前,让我们先回顾一下各种上下文切换技术. 不过首先说明一点术语.当我们说"上下文"的时候,指的是程序在执行中的一个状态.通常我们会用调用栈来表示这个状态--栈记载了每个调 ...

  7. 教你在Python中构建物体检测系统(附代码、学习资料)

    作者:FAIZANSHAIKH 翻译:闫晓雨 校对:张玲 本文约3200字,建议阅读10分钟. 本文介绍物体检测技术以及解决此领域问题的几种不同方法,带你深入研究在Python中如何构建我们自己的对象 ...

  8. python中父子进程

    最近在使用python中的multiprocessing模块时遇到一些问题,很多人应该遇到相同问题,简单研究下,供有需要的参考. 首先,要明白multiprocessing的出现很大程度是为了解决py ...

  9. Python中的进程和线程(20)

    进程和线程 进程 创建多进程 进程和全局变量 传递参数和进程号 进程的状态 进程之间通信 put() get()方法 生产者和消费者 进程子类化 生产者和消费者子类化 进程池 线程 线程子类化 共享全 ...

最新文章

  1. docker 镜像修改的配置文件自动还原_Docker 基础与实战,看这一篇就够了
  2. C#面向对象名词比较(一)
  3. Django之form表单组件、cookie与session
  4. 关于java_关于Java基础
  5. css选择器按功能分,CSS 选择器
  6. 刷题笔记2020-06-26
  7. Ranger-Usersync安装
  8. python去重复记录_python如何处理重复值数据?
  9. 产品经理 - 汽车维修连锁企业 - 发展预测
  10. Linux设备模型:kset, kobj, ktype
  11. 【李宏毅2020 ML/DL】P85 Transfer Learning
  12. 苹果x翻新机序列号开头_Android翻新电话每隔X秒
  13. 小米wifi怎么创建虚拟服务器,小米路由器玩法:一键安装LLMP 建自己的网站
  14. MATLAB编程算矩阵,MatLab矩阵计算
  15. linux redis5.0 集群搭建
  16. 3个方法恢复彻底删除的苹果手机视频!
  17. win10系统如何看服务器地址,win10查看电脑DNS服务器地址具体步骤
  18. 公纵号发送提示信息(用户微服务--消息微服务)
  19. Java实验作业11(Math)
  20. 打造卓越游戏 | 2023 Google 游戏开发者峰会

热门文章

  1. 阿里云注销备案流程及注销备案常见问题与解答
  2. opencv的透视变换(投影变换)
  3. 数据分析中的专业术语
  4. linux执行rm -rf /*命令后的效果原来是这样
  5. Stream流式计算
  6. 利用MATLAB命令求解运输问题
  7. Vim - 官方网站
  8. MATLAB 多项式计算
  9. 翻译app上的图片文字信息提取好神奇?如何实现一个文字图片识别程序
  10. php redis 删除key 通配符,php redis 批量删除keys的方法