20.17 Psutil模块详解
官方文档(psutil 5.4.7 ):https://psutil.readthedocs.io/en/latest/
本文为阅读官方文档时的笔记,方便日后查阅。
psutil(python系统和流程实用程序)是一个跨平台库,用于在Python中检索有关正在运行的进程和系统利用率(CPU,内存,磁盘,网络,传感器)的信息。它主要用于系统监视,分析,限制进程资源和运行进程的管理。它实现了UNIX命令行工具提供的许多功能,例如:ps,top,lsof,netstat,ifconfig,who,df,kill,free,nice,ionice,iostat,iotop,uptime,pidof,tty,taskset,pmap。
pip install psutil
注意:在Linux上安装时,需要实现安装gcc。在一个最小化安装的服务器上,需要进行如下安装步骤:
yum install -y gcc python-devel python-pip
pip install psutil
git clone https://github.com/giampaolo/psutil.git
cd psutil
python setup.py install
以上函数会以命名元组的形式返回系统CPU时间。每个属性表示CPU在给定模式下花费的时间。属性可用性因平台而异:
- user:在用户空间(user mode)下,进程执行所花费的时间;
- system:在内核模式下进程执行所花费的时间;
- idel:cpu等待的时间
>>> 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)
>>> psutil.cpu_times().user
17411.7
返回一个浮点数,表示当前系统CPU利用率百分比。当interval> 0.0时,比较间隔之前和之后经过的系统CPU时间(阻塞)。当interval为0.0或None时,比较自上次调用或模块导入后经过的系统CPU时间, 结果会立即返回。所以第一次使用interval = 0.0或None调用此函数时,它将返回一个无意义的0.0值。为了提高函数准确性,建议interval至少0.1秒。当percpu为True时,返回一个浮点列表,表示利用率为每个CPU的百分比。列表的第一个元素是指第一个CPU,第二个元素是第二个CPU,依此类推。
>>> import psutil
>>> # blocking
>>> psutil.cpu_percent(interval=1)
2.0
>>> # non-blocking (percentage since last call)
>>> psutil.cpu_percent(interval=None)
2.9
>>> # blocking, per-cpu
>>> psutil.cpu_percent(interval=1, percpu=True)
[2.0, 1.0]
>>>
返回逻辑cpu的个数,当logical=True时,则返回物理cpu的个数。
示例:具有2个超线程的物理cpu的服务器上:
>>> import psutil
>>> psutil.cpu_count()
4
>>> psutil.cpu_count(logical=False)
2
以命名元组的形式返回各种cpu统计信息。
ctx_switches:启动后的上下文切换次数(自愿+非自愿)。
interrupts :自启动后的中断数。
soft_interrupts:自启动后的软件中断次数。在Windows和SunOS上始终为0。
syscalls:自启动后的系统调用次数。在Linux上始终设置为0。
>>> import psutil
>>> psutil.cpu_stats()
scpustats(ctx_switches=20455687, interrupts=6598984, soft_interrupts=2134212, syscalls=0)
将CPU频率以命名元组返回,包括以Mhz单位表示的当前频率,最小和最大频率。在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)]
以命名元组的形式返回内存使用相关信息。单位为bytes。
- total: 内存的总大小.
- available: 可以用来的分配的内存,不同系统计算方式不同; Linux下的计算公式:free+ buffers +cached
- percent: 已经用掉内存的百分比 (total - available) / total * 100.
- used: 已经用掉内存大小,不同系统计算方式不同
- free: 空闲未被分配的内存,Linux下不包括buffers和cached
Platform-specific fields:
- active: (UNIX): 最近使用内存和正在使用内存。
- inactive: (UNIX): 已经分配但是没有使用的内存
- buffers: (Linux, BSD): 缓存,linux下的Buffers
- cached:(Linux, BSD): 缓存,Linux下的cached.
- wired: (BSD, OSX): 一直存在于内存中的部分,不会被移除
- shared: (BSD): 缓存
内存总大小不等于Used+available,在windows系统可用内存和空闲内存是用一个。
>>> 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")
将swap统计信息以命名元组的形式返回。
- total: swap的总大小 单位为bytes
- used: 已用的swap大小 bytes
- free: 空闲的swap大小 bytes
- percent: 已用swap的百分比
- sin: 从磁盘调入是swap的大小
- sout: 从swap调出到disk的大小
sin, sout在windows没有意义。
>>> import psutil
>>> psutil.swap_memory()
sswap(total=2097147904L, used=886620160L, free=1210527744L, percent=42.3, sin=1050411008, sout=1906720768)
将所有已挂载的磁盘分区作为命名元组列表返回,包括设备,挂载点和文件系统类型,类似于UNIX上的“df”命令。
如果all=False 它会仅返回物理设备,忽略类似内存分区(/dev/shm )的其他类型的设备,注意这个操作并不是完全可靠的。
>>> 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')]
将给定路径所在的分区的磁盘使用情况统计信息作为命名元组返回,包括以字节为单位的总空间,已用空间和可用空间,以及百分比使用情况。如果path不存在,则引发OSError。
>>> import psutil
>>> psutil.disk_usage('/')
sdiskusage(total=21378641920, used=4809781248, free=15482871808, percent=22.5)
将系统级别的磁盘I/O统计信息作为命名元组返回,包括以下字段:
- read_count:读取次数
- write_count:写入次数
- read_bytes:读取的字节数
- write_bytes:写入的字节数
- read_time:从磁盘读取的时间(以毫秒为单位)
- write_time:写入磁盘所花费的时间(以毫秒为单位)
>>> 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)}
将系统级别的网络I/O统计信息作为命名元组返回,包括以下属性:
- bytes_sent:发送的字节数
- bytes_recv:接收的字节数
- packets_sent:发送的包数
- packets_recv:接收的包数
- errin:接收时的错误总数
- errout:发送时的错误总数
- dropin:丢弃的传入数据包总数
- dropout:丢弃的传出数据包总数(macOS和BSD总是0)
>>> 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)}
将系统范围的套接字连接作为命名元组列表返回。每个命名元组都提供7个属性:
- fd:套接字的文件描述符。如果连接引用当前进程,则可以将其传递给socket.fromfd()以获取可用的套接字对象。在Windows和SunOS上,它始终设置为-1。
- family:地址族,值为AF_INET,AF_INET6或AF_UNIX。
- type:连接类型,SOCK_STREAM(TCP)或SOCK_DGRAM(UDP)。
- laddr:连接的本地地址,为(ip,port)命名元组或AF_UNIX套接字的路径。
- raddr:连接的远程地址,为(ip,port)命名元组或者是UNIX套接字的绝对路径。当远程端点未被连接到时,您将获得一个空元组(AF_INET *)或“”(AF_UNIX)。
- status:表示TCP连接的状态。返回值是psutil.CONN_ *常量之一(字符串,如ESTABLISHED、CLOSING等)。对于UDP和UNIX套接字,这始终是psutil.CONN_NONE。
- pid:打开套接字的进程的PID,如果不能被检索则为None。在某些平台(例如Linux)上,此字段可能需要root权限。
kind参数是一个字符串,用于过滤符合以下条件的连接:
| Kind value | Connections using |
|---|---|
"inet" | IPv4 and IPv6 |
"inet4" | IPv4 |
"inet6" | IPv6 |
"tcp" | TCP |
"tcp4" | TCP over IPv4 |
"tcp6" | TCP over IPv6 |
"udp" | UDP |
"udp4" | UDP over IPv4 |
"udp6" | UDP over IPv6 |
"unix" | UNIX socket (both UDP and TCP protocols) |
"all" | the sum of all the possible families and protocols |
示例:
>>> 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)
...]
将系统上安装的每个NIC(网络接口卡)关联的地址作为字典返回,该字典的键是NIC名称,值是分配给NIC的每个地址的命名元组列表。每个命名元组包括5个字段:
family:地址族,可选值:AF_INET(值为2),AF_INET6(值为10)或AF_LINK(值为17,指向MAC地址)。
address: 网卡地址(IP或MAC)
netmask:网络掩码地址(可以是None)。
broadcast :广播地址(可以是None)。
ptp:代表“点对点”;它是点对点接口(通常是VPN)上的目标地址。broadcast 和ptp是互斥的。(可以是None)。
>>> 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)]}
>>>
一个获取主机ip的小例子:
mport psutil
def get_ip():
"""
获取网卡名称和ip地址
:return: list(tuple), 例如:[('eth0', '192.168.5.242')]
"""
netcard_info = []
info = psutil.net_if_addrs()
for k, v in info.items():
for item in v:
if item[0] == 2 and not item[1] == '127.0.0.1':
netcard_info.append((k, item[1]))
return netcard_info
if __name__ == '__main__':
print get_ip()
网卡统计信息。将系统上安装的每个NIC(网络接口卡)的信息作为字典返回,该字典的键是NIC名称,值是带有以下字段的命名元组:
- isup :布尔值,用于表名网卡是否处于启动状态(up)
- duplex: 双工通信类型;可选值:NIC_DUPLEX_FULL(全双工),NIC_DUPLEX_HALF(半双工),NIC_DUPLEX_UNKNOWN。
- speed: 以兆位(MB)为单位表示的NIC速度,如果无法确定(例如’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)}
返回硬件温度。每个条目都是一个命名元组,代表某个硬件温度传感器(它可能是CPU,硬盘或其他东西,具体取决于操作系统及其配置)。除非将华氏温度fahrenheit设置为真,否则所有温度均以摄氏度表示。
>>> 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),
返回硬件风扇速度。每个条目都是一个命名元组,代表某个硬件传感器风扇。风扇速度以RPM(每分钟轮数)表示。如果OS不支持传感器,则返回空的dict。例:
>>> import psutil
>>> psutil.sensors_fans()
{'asus': [sfan(label='cpu_fan', current=3200)]}
将电池状态信息作为命名元组返回,包括以下值。如果未安装电池或无法确定指标,则返回None。
- percent :电池剩余百分比。
- secsleft: 电池电量耗尽前剩余的秒数的粗略近似值。如果连接了交流电源线,则将其设置为psutil.POWER_TIME_UNLIMITED。如果无法确定,则将其设置为psutil.POWER_TIME_UNKNOWN。
- power_plugged: 如果连接了交流电源线,则为真,否则为假;如果无法确定,则为无。
>>> import psutil
>>>
>>> def secs2hours(secs): #将秒数转换为hh:mm:ss的格式
... 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
返回的系统启动时间,以时间戳的形式表示。
>>> 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'
以命名元组列表的形式返回当前系统上连接的用户,包括以下字段:
- user:用户的名称。
- terminal:与用户关联的终端,tty或伪tty,如果没有,为None。
- host:与条目关联的主机名(如果有的话)。
- start:条目创建时间(用户登录时间),以时间戳的形式。
- 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)]
返回当前运行的PID列表。要迭代所有进程并避免竞争条件,应首选process_iter()函数。
>>> import psutil
>>> psutil.pids()
[1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17, 18, 19, ..., 32498]
返回一个迭代器,为本地计算机上的所有正在运行的进程生成一个Process类实例。每个实例只创建一次,然后缓存到内部表中,每次生成一个元素时都会更新这个内部表。缓存的Process实例会被做身份验证,这样当一个PID被别的进程复用的时候,缓存的Process实例会被更新。如果指定了attrs,则会在内部调用Process.as_dict()方法,并将生成的dict存储为info属性,该属性附加到返回的Process实例。如果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'}
...
使用attrs参数的更紧凑版本(推荐):
>>> 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}]
检查当前进程列表中是否存在给定的PID。这比在psutil.pids()中执行pid更快,推荐使用。
Convenience function which waits for a list of Process instances to terminate. Return a (gone, alive) tuple indicating which processes are gone and which ones are still alive. The gone ones will have a new returncode attribute indicating process exit status (will be None for processes which are not our children). callback is a function which gets called when one of the processes being waited on is terminated and a Process instance is passed as callback argument). This function will return as soon as all processes terminate or when timeout (seconds) occurs. Differently from Process.wait() it will not raise TimeoutExpired if timeout occurs. A typical use case may be:
- send SIGTERM to a list of processes
- give them some time to terminate
- send SIGKILL to those ones which are still alive
Example which terminates and waits all the children of this process:
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()
表示具有给定pid的操作系统进程。pid缺省时,表示当前进程pid,即os.getpid();如果给定的pid不存在,则会触发NoSuchProcess异常。在Linux上,pid也可以引用线程ID,即Process().threads()方法返回的id字段)。
Process是通过pid绑定的。如果在一个Process实例,在psutil运行中pid进程死掉,而 这个pid又绑定给了别的新的进程。为了保证Process的安全性可以通过pid+createion time 方式来确认进程是否是同一个。
方法与属性:
进程id
父进程的PID。如果进程变成了一个僵尸进程,其ppid会改变。
进程名称
进程的绝对路径
>>> import psutil
>>> psutil.Process().exe()
'/usr/bin/python2.7'
进程的命令行,返回一个列表
>>> import psutil
>>> psutil.Process().cmdline()
['python', 'manage.py', 'runserver']
进程的环境变量,返回一个字典。
>>> 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'}
进程的创建时间,返回一个浮点型的时间戳。
>>> 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'
将进程的多个信息处理成一个字典。attrs是一个列表,指定进程的属性,例如[‘cpu_times’, ’name’];如果不指定attrs,则默认为全部属性。
>>> import psutil
>>> p = psutil.Process()
>>> p.as_dict(attrs=['pid', 'name', 'username'])
{'username': 'giampaolo', 'pid': 12366, 'name': 'python'}
将父进程作为Process对象返回。如果没有父PID,则返回None。
当前进程的状态,是一个字符串。其值是psutil.STATUS_* 常量之一。
进程的当前工作目录,是一个绝对路径。
拥有该进程的用户的名称。是进程uid对应的用户。
进程的用户id,是一个命名元组。类似于os.getresuid()
进程的用户组id,是一个命名元组。类似于os.getresgid()
与此进程关联的终端(如果有),否则为None。
获取或设置进程的nice值(优先级)。在UNIX上,这是一个通常从-20到20的数字。nice值越高,进程的优先级越低。
>>> import psutil
>>> p = psutil.Process()
>>> p.nice(10) # set
>>> p.nice() # get
10
获取或设置进程I/O的nice值(优先级)。在Linux上,ioclass是psutil.IOPRIO_CLASS_* 常量之一。value是一个从0到7的数字。值越高,进程的I/O优先级越低。在Windows上只使用ioclass,它可以设置为2(正常),1(低)或0(非常低)。
下面的示例为当前进程设置IDLE优先级,这意味着只有当其他进程不需要磁盘时才会获得I/O时间:
>>> import psutil
>>> p = psutil.Process()
>>> p.ionice(psutil.IOPRIO_CLASS_IDLE) # set
>>> p.ionice() # get
pionice(ioclass=<IOPriority.IOPRIO_CLASS_IDLE: 3>, value=0)
>>>
获取或设置进程的资源限制。resource是 psutil.RLIMIT_* 变量值之一。limits是一个(soft, hard)元组。类似于 resource.getrlimit() 和resource.setrlimit() 。获取进程的资源限制时,返回值是一个(soft, hard)元组,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)
>>>
进程的io信息。
>>> 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)
此进程的上下文切换次数(累计)
此进程当前打开的文件描述符数(非累积)。
此进程当前使用的句柄数(非累积)。
此进程当前使用的线程数(非累积)。
返回进程打开的线程信息,是一个包含线程ID和CPU时间(user/system) 命名元组。在OpenBSD上,此方法需要root权限。
返回一个命名元组,(user,system,children_user,children_system),表示累积的进程时间。
返回一个浮点,表示进程CPU利用率百分比,如果进程在不同的CPU上运行多个线程,也可以> 100.0。
>>> 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亲和性。CPU亲和性包括告诉操作系统仅在有限的一组CPU上运行进程,这样能减少上下文切换。如果没有传递cpus参数,则返回当前CPU亲和性,是个整数列表。如果传递cpus参数,它必须是指定新CPU亲和性的整数列表,例如[0, 1]。如果传递空列表,则重置所有符合条件的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([])
返回当前进程正在多少个cpu上运行。
返回进程使用的相关内存信息组成的命名元组。
- rss: aka “Resident Set Size”, this is the non-swapped physical memory a process has used. On UNIX it matches “top“‘s RES column (see doc). On Windows this is an alias for wset field and it matches “Mem Usage” column of taskmgr.exe.
- vms: aka “Virtual Memory Size”, this is the total amount of virtual memory used by the process. On UNIX it matches “top“‘s VIRT column (see doc). On Windows this is an alias for pagefile field and it matches “Mem Usage” “VM Size” column of taskmgr.exe.
- shared: (Linux) memory that could be potentially shared with other processes. This matches “top“‘s SHR column (see doc).
- text (Linux, BSD): aka TRS (text resident set) the amount of memory devoted to executable code. This matches “top“‘s CODE column (see doc).
- data (Linux, BSD): aka DRS (data resident set) the amount of physical memory devoted to other than executable code. It matches “top“‘s DATA column (see doc).
- lib (Linux): the memory used by shared libraries.
- dirty (Linux): the number of dirty pages.
- pfaults (macOS): number of page faults.
- pageins (macOS): number of actual pageins.
>>> import psutil
>>> p = psutil.Process()
>>> p.memory_info()
pmem(rss=15491072, vms=84025344, shared=5206016, text=2555904, lib=0, data=9891840, dirty=0)
类似于memory_info()
将进程内存与总物理系统内存进行比较,并以百分比形式计算进程内存利用率memtype参数是一个字符串,用于指示要与哪种类型的进程内存进行比较。
将进程的映射内存区域返回为命名元组的列表,其字段根据平台而变化。此方法对于获取进程内存使用情况的详细表示非常有用,如此处所述(最重要的值是“私有”内存)。如果grouped为True,则将具有相同路径的映射区域组合在一起,并将不同的内存字段相加。如果grouped为False,则每个映射区域显示为单个实体,命名元组还将包括映射区域的地址空间(addr)和权限集(perms)。
>>> 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),
pmmap_grouped(path='/lib/x8664-linux-gnu/libcrypto.so.0.1', rss=34124, rss=32768, size=2134016, pss=15360, shared_clean=24576, shared_dirty=0, private_clean=0, private_dirty=8192, referenced=24576, anonymous=8192, 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.memory_maps(grouped=False)
[pmmap_ext(addr='00400000-006ea000', perms='r-xp', path='/usr/bin/python2.7', rss=2293760, size=3055616, pss=1157120, shared_clean=2273280, shared_dirty=0, private_clean=20480, private_dirty=0, referenced=2293760, anonymous=0, swap=0),
pmmap_ext(addr='008e9000-008eb000', perms='r--p', path='/usr/bin/python2.7', rss=8192, size=8192, pss=6144, shared_clean=4096, shared_dirty=0, private_clean=0, private_dirty=4096, referenced=8192, anonymous=4096, swap=0),
pmmap_ext(addr='008eb000-00962000', perms='rw-p', path='/usr/bin/python2.7', rss=417792, size=487424, pss=317440, shared_clean=200704, shared_dirty=0, private_clean=16384, private_dirty=200704, referenced=417792, anonymous=200704, swap=0),
pmmap_ext(addr='00962000-00985000', perms='rw-p', path='[anon]', rss=139264, size=143360, pss=139264, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=139264, referenced=139264, anonymous=139264, swap=0),
pmmap_ext(addr='02829000-02ccf000', perms='rw-p', path='[heap]', rss=4743168, size=4874240, pss=4743168, shared_clean=0, shared_dirty=0, private_clean=0, private_dirty=4743168, referenced=4718592, anonymous=4743168, swap=0),
...]
将此进程的子进程作为Process实例列表返回。如果recursive为True,则递归返回所有子进程。
伪代码示例:假设A为p进程:
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
将进程打开的文件作为一个命名元组列表返回。
>>> 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)]
将进程的连接作为一个命名元组列表返回。
>>> 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')]
给进程发送信号( signal module )。在UNIX上,这与os.kill(pid, sig) 相同。在Windows上仅支持SIGTERM,CTRL_C_EVENT和CTRL_BREAK_EVENT信号,SIGTERM被视为kill()的别名.
使用SIGSTOP信号暂停进程执行。在UNIX上,这与os.kill(pid, signal.SIGSTOP) 相同。在Windows上,这是通过挂起所有进程线程执行来完成的。
使用SIGCONT信号恢复进程执行。在UNIX上,这与os.kill(pid, signal.SIGCONT) 相同。在Windows上,这是通过恢复所有进程线程执行来完成的。
使用SIGTERM信号终止进程。在UNIX上,这与os.kill(pid, signal.SIGTERM) 相同。在Windows上,这是kill()的别名。
使用SIGKILL信号kill当前进程。在UNIX上,这与os.kill(pid, signal.SIGKILL) 相同。在Windows上,这是通过使用TerminateProcess完成的。
等待进程终止,如果进程是档期某个进程的子进程,也返回退出代码,否则返回None。
>>> import psutil
>>> p = psutil.Process(9891)
>>> p.terminate()
>>> p.wait()
0
类似于 subprocess.Popen 。它启动一个子进程,你完全像使用subprocess.Popen时那样处理它,但是它还提供了psutil.Process类的所有方法。
>>> 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语句的上下文管理器。退出时,将关闭标准文件描述符,并等待该进程。
>>> import psutil, subprocess
>>> with psutil.Popen(["ifconfig"], stdout=subprocess.PIPE) as proc:
>>> log.write(proc.stdout.read())