python--cProfile,memory_profiler,psutil
关于测试代码用了多长时间,我们之前介绍了timeit。相较于timeit,python中还有一个更加强大的模块,cProfile模块
(提到cProfile,其实还有一个profile,但profile和cProfile用法一样,效果没有cProfile好,因此便不介绍了,也推荐使用cProfile模块)
在一个函数中,timeit模块只能看这个函数整体花了多长时间,却无法得到函数中的某个部分花了多长时间。
因此接下来,我们将介绍cProfile模块
import cProfile
import time
def sub_func():
time.sleep(0.001)
def func():
s = 0
for i in range(1000):
s += i
sub_func()
return s
if __name__ == '__main__':
cProfile.run("func()")
# 程序运行结果
'''
2004 function calls in 0.999 seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.999 0.999 <string>:1(<module>)
1000 0.003 0.000 0.995 0.001 profile模块.py:4(sub_func)
1 0.005 0.005 0.999 0.999 profile模块.py:7(func)
1 0.000 0.000 0.999 0.999 {built-in method builtins.exec}
1000 0.991 0.001 0.991 0.001 {built-in method time.sleep}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
'''
# ncalls:函数的某一段代码调用的次数,可以看出由于循环了一千次,sub_func,和内置函数time.sleep各运行了一千次
# tottime:函数的某一段代码总共的运行时间,但是要除去函数中调用其他函数所花的时间。个人认为最具有参考意义,可以看到每一个部分的执行时间。第二个tottime意义不大
# percall:函数的某一段代码运行一次的平均时间,等同于tottime/ncalls
# cumtime:函数的某一段代码总共的运行时间,包括函数中调用其他函数所花的时间。比如第一行,第一个tottime是0.000,但是第二个tottime要加上调用其他函数的时间,因此变成了0.999
# percall:函数运行一次的平均时间,等同于cumtime/ncalls
# filename:lineno(function):函数所在的文件名,函数在哪一行(函数名)
'''
可以看出,sub_func被调用了一千次,导致time.sleep内置函数被调用了一千次,因此用了0.991s,程序用时主要在这一段代码上
'''
与此同时,还有一个比较相似的模块叫做memory_profiler,不同的是,该模块是用来监视每一行代码的内存消耗的
可以通过pip来安装此模块,但安装的同时也最好安装psutil(process and system utilities)模块,不过根据我的情况,当安装memory_profiler模块的时候,psutil会自动安装
通过几个简单例子来看看这个模块怎么使用,以及了解一下python关于赋值以及垃圾回收的原理
from memory_profiler import profile
import time
# 关于memory_profiler,我们主要使用该模块下的一个函数,用这个函数作为装饰器,对函数进行装饰
@profile
def test():
a = "a"*1024*1024*20 # 生成20M的字符串
b = "b"*1024*1024 #生成1M的字符串
time.sleep(3)
del a
print("古明地盆")
if __name__ == '__main__':
test()
# 程序运行结果
'''
古明地盆
Filename: C:/Users/Administrator/Desktop/py/1.py
Line # Mem usage Increment Line Contents
================================================
4 15.8 MiB 15.8 MiB @profile
5 def test():
6 35.8 MiB 20.0 MiB a = "a"*1024*1024*20 # 生成20M的字符串
7 36.8 MiB 1.0 MiB b = "b"*1024*1024 #生成1M的字符串
8 36.8 MiB 0.0 MiB time.sleep(3)
9 16.8 MiB -20.0 MiB del a
10 16.8 MiB 0.0 MiB print("古明地盆")
'''
# Line表示代码的行数,记录了代码所在的每一行
# Mem usage记录了总共所用的内存
# Increment记录了每一行所用的内存
# Line Contents则是记录了所写的代码
# 分析
'''
可以看出,当我们使用@profile对test函数进行装饰的时候,消耗了15.8M的内存
在生成20M的字符串a时,Increment显示消耗了20M,而Mem usage表示消耗的内存的累加和,此时变成了35.8M
在生成1M的字符串b时,Increment显示消耗了1M,Mem usage变成36.8M
time.sleep(3),程序在休眠的时候,不消耗内存,所以没有变化,其实此时cpu也不会被消耗
del a,当我们删除a,Increment则是-20M,表示内存消耗减少了20M,即有20M的内存被释放了,同时Mem usage也减少了20M
使用print函数打印之后程序结束
'''
from memory_profiler import profile
@profile
def test():
a = "a"*1024*1024*20 # 依旧生成20M的字符串
a = "b"*1024*1024*10 #此时将a重新赋值
a = "c"*1024*1024
del a
if __name__ == '__main__':
test()
# 运行结果
'''
Filename: C:/Users/Administrator/Desktop/py/2.py
Line # Mem usage Increment Line Contents
================================================
3 15.3 MiB 15.3 MiB @profile
4 def test():
5 35.3 MiB 20.0 MiB a = "a"*1024*1024*20 # 依旧生成20M的字符串
6 25.3 MiB -10.0 MiB a = "b"*1024*1024*10 #此时将a重新赋值
7 16.3 MiB -9.0 MiB a = "c"*1024*1024
8 15.3 MiB -1.0 MiB del a
'''
# 分析
'''
首先还是使用@profile对test装饰,消耗了15.8M的内存
创建20M的字符串时消耗了20M的内存
但当给a重新赋值之后,可以看到内存被释放了10M
在python中,给一个变量赋值的时候,会先在内存中申请一份空间,将这个值存起来,然后让这个变量指向它
比如这里的a = "a"*1024*1024*20,会现在内存中创建一个20M字符串,然后让a的内存指针指向这个20M的字符串所在的内存地址
然后当a = "b"*1024*1024*10时,还是一样会现在内存中申请一份空间,将这个内存为10M的字符串存起来,然后让a指向它
因此此时,a便不再指向之前那个20M的字符串,而是指向新的这个10M的字符串,那么之前的那个字符串便没有变量所指向
python自带了一个引用计数器,会检测值有没有被使用,主要就是看该值的引用计数是否为零
每当有一个变量指向它,引用计数便会加一。在这里a已经指向了别的地址,那么之前的那个20M字符串便成为了了垃圾,因此被回收掉了
因此回收掉20M旧的字符串,增加了10M新的字符串,整体还是释放了10M
同理,a = "c"*1024*1024,内存释放了9M
最后del a,内存释放了9M
'''
from memory_profiler import profile
@profile
def test():
a = "a"*1024*1024*20 # 依旧生成20M的字符串
b = a
c = b
del a
del b
del c
if __name__ == '__main__':
test()
# 程序运行结果
'''
Filename: C:/Users/Administrator/Desktop/py/3.py
Line # Mem usage Increment Line Contents
================================================
3 15.3 MiB 15.3 MiB @profile
4 def test():
5 35.3 MiB 20.0 MiB a = "a"*1024*1024*20 # 依旧生成20M的字符串
6 35.3 MiB 0.0 MiB b = a
7 35.3 MiB 0.0 MiB c = b
8 35.3 MiB 0.0 MiB del a
9 35.3 MiB 0.0 MiB del b
10 15.3 MiB -20.0 MiB del c
'''
# 分析
'''
直接从第六行开始分析
可以看出b = a,内存消耗没有变化,因为python是引用传递
b = a,这句话的含义并不是b随着a变化而变化,b和a之间没有关系。
只是因为每一个变量都要指向一个内存地址,可以理解为b不知道该指向谁,但是b = a
于是b对a说:我和你相等,你指向谁我就指向谁,所以你指向谁啊
a回答b:我只想的是一个20M的字符串
于是b也指向了这个20M的字符串,b = a只是代表了a是一个引路人,b通过a找到了自己应该指向的地址
现在两个变量都指向了同一份地址,因此20M字符串的字符串只有一份,因此b = a,不会使内存增加
只是这个值现在有两个变量指向它
c = b,同理这行代码,依旧不会使内存增加
当del a的时候,内存依旧没有变化。还记得之前说的引用计数吗?只要有变量指向某一个值,那么改值的引用计数便不会为零,只要不为零,便不会被视为垃圾,当然也不会被回收
可以明显看出a,b,c三个变量都指向了这个值,那么该值的引用计数便是3
del a,引用计数变为2
del b,引用计数变为1
del c,引用计数变为0
因此当del c的时候,引用计数才为0,此时被视为垃圾,进行回收,因此内存释放了20M
'''
psutil模块主要是用来检测系统的运行状态
import psutil
print(psutil.cpu_count()) # 获取cpu的逻辑数量
'''
4
'''
print(psutil.cpu_count(logical=True)) # 如果加上这个参数,表示获取cpu物理核心
'''
4
'''
# 如果结果为2,说明是二核超线程,结果为4说明是四核非超线程
# 统计CPU的用户/系统/空闲时间
print(psutil.cpu_times())
'''
scputimes(user=12420.643618999999, system=4348.7930767, idle=46156.6866743, interrupt=311.86159910000003, dpc=480.8730825)
'''
# 再实现类似top命令的CPU使用率,每0.5s刷新一次,累计10次
for x in range(10):
print(psutil.cpu_percent(interval=0.5,percpu=True))
'''
[12.5, 3.1, 6.2, 18.7]
[6.2, 0.0, 0.0, 9.1]
[26.5, 3.1, 3.1, 0.0]
[27.3, 3.1, 9.4, 21.9]
[9.4, 12.5, 15.6, 21.9]
[6.3, 15.6, 6.2, 25.0]
[18.2, 3.1, 3.1, 6.3]
[12.5, 0.0, 12.5, 0.0]
[12.5, 12.5, 21.9, 18.2]
[9.4, 12.5, 21.9, 18.7]
'''
# 获取内存信息
# 获取物理内存信息
print(psutil.virtual_memory())
'''
svmem(total=12773879808, available=5167751168, percent=59.5, used=7606128640, free=5167751168)
'''
# 可以看出total=12773879808表示内存总大小,以字节表示。12773879808/1024/1024/1024=11.9G,used表示已经使用的内存,占了59.5(percent),available表示可用内存
# 获取交换内存信息
print(psutil.swap_memory())
'''
sswap(total=25545875456, used=8012619776, free=17533255680, percent=31.4, sin=0, sout=0)
'''
# total=25545875456表示交换区内存,25545875456/1024/1024/1024=23.8G
# 关于物理内存和交换内存以及虚拟内存之间的区别
'''
物理内存:就是实际的内存条提供的临时数据存储空间,在windows上右键点击计算机,显示属性时,上面显示的安装内存(RAM),就是电脑的物理内存。
这些内存是实际存在的,在你不给机器增加内存条的时候是不会改变的
交换内存:交换内存是专门用来临时存储数据的,通常在页面调度和交换进程数据时使用。相当于在进行内存整理的时候,会先把部分数据放在硬盘的某个地方,类似我们整理衣柜,
衣服一多直接整理会很麻烦,因此会先把部分衣服放在其他地方,等衣柜里的衣服整理完了再把放在其他地方的衣服拿回来。这个其他地方放在计算机中则代表硬盘的某个
地方,也就是我们所说的交换区,通常交换内存应该是物理内存的2到4倍,我使用的电脑是23.8/11.9=2倍
通常当使用交换内存时,以为这物理内存不足,正所谓衣柜,如果衣服不多那就没必要拿出部分衣服放在其他地方,直接在衣柜里就能解决了
虚拟内存:首先,如果想要操作文件,可执行程序等等,那么首先要把它们从磁盘上读取到内存中,因此cpu除了自己的那一部分小小的空间外,要想操作数据,只能操作内存里的数据
但是当内存不够了,那么便会在硬盘上开辟一份虚拟内存,将物理内存里的部分数据放在虚拟内存当中。硬盘的空间很大,即使普通电脑安装的固态硬盘也有一百个G,因此
可以拿出一部分充当虚拟内存。不过虚拟内存虽说是内存,但毕竟在硬盘上,速度绝对和cpu直接从物理内存里读取数据的速度相差甚远。
这也是为什么那些大型网站将经常被访问的一些数据放在redis缓存里,而不是放在硬盘或者数据库上
'''
import psutil
from pprint import pprint
# 获取磁盘信息
# 可以通过psutil获取磁盘分区、磁盘使用率和磁盘IO信息
print(psutil.disk_partitions()) # 磁盘分区信息
'''
[sdiskpart(device='C:\\', mountpoint='C:\\', fstype='NTFS', opts='rw,fixed'),
sdiskpart(device='D:\\', mountpoint='D:\\', fstype='NTFS', opts='rw,fixed'),
sdiskpart(device='E:\\', mountpoint='E:\\', fstype='NTFS', opts='rw,fixed')]
'''
# 可以看到一共有三个盘符,fstype表示文件系统格式是NTFS,opts中的rw表示可读写
print(psutil.disk_usage("C:\\")) # 磁盘使用情况
'''
sdiskusage(total=53683941376, used=28532375552, free=25151565824, percent=53.1)
'''
# 可以看到C盘总容量total=53683941376,大概50G,used表示已经使用,可以看到已经使用了percent(53.1)
# 同时也可以看其他盘符的使用信息
# 获取网络信息
# psutil可以获取网络接口和网络连接信息
print(psutil.net_io_counters()) # 获取网络读写字节/包的个数
'''
snetio(bytes_sent=444225733, bytes_recv=12087394033, packets_sent=5359520, packets_recv=8847435, errin=0, errout=0, dropin=0, dropout=0)
'''
pprint(psutil.net_if_addrs()) # 获取网络接口信息
'''
{'Loopback Pseudo-Interface 1': [snicaddr(family=<AddressFamily.AF_INET: 2>, address='127.0.0.1', netmask='255.0.0.0', broadcast=None, ptp=None),
snicaddr(family=<AddressFamily.AF_INET6: 23>, address='::1', netmask=None, broadcast=None, ptp=None)],
'本地连接': [snicaddr(family=<AddressFamily.AF_LINK: -1>, address='FC-AA-14-8E-F3-56', netmask=None, broadcast=None, ptp=None),
snicaddr(family=<AddressFamily.AF_INET: 2>, address='192.168.1.37', netmask='255.255.255.0', broadcast=None, ptp=None)]}
'''
# 获取当前的网络信息,使用net_connections()
pprint(psutil.net_connections())
'''
[sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59323), raddr=addr(ip='74.125.204.101', port=443), status='SYN_SENT', pid=2268),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59224), raddr=addr(ip='192.168.1.251', port=5761), status='ESTABLISHED', pid=2532),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=8868), raddr=(), status='LISTEN', pid=2488),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49158), raddr=addr(ip='192.168.1.251', port=5773), status='ESTABLISHED', pid=4),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=49168), raddr=(), status='LISTEN', pid=1780),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=7281), raddr=(), status='LISTEN', pid=1664),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49236), raddr=addr(ip='192.168.1.251', port=22201), status='ESTABLISHED', pid=3220),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=52309), raddr=addr(ip='115.159.4.107', port=80), status='CLOSE_WAIT', pid=2588),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59278), raddr=addr(ip='125.39.213.39', port=80), status='ESTABLISHED', pid=5480),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59289), raddr=addr(ip='192.168.1.252', port=6688), status='TIME_WAIT', pid=0),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=4500), raddr=(), status='NONE', pid=920),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=49171), raddr=(), status='LISTEN', pid=720),
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=1, laddr=addr(ip='::', port=49161), raddr=(), status='LISTEN', pid=920),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=5355), raddr=(), status='NONE', pid=1124),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=50928), raddr=addr(ip='127.0.0.1', port=50927), status='ESTABLISHED', pid=6560),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=18385), raddr=addr(ip='127.0.0.1', port=49188), status='ESTABLISHED', pid=1392),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49220), raddr=addr(ip='192.168.1.251', port=22201), status='ESTABLISHED', pid=3220),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=49345), raddr=(), status='NONE', pid=1672),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='127.0.0.1', port=55397), raddr=(), status='NONE', pid=3176),
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=1, laddr=addr(ip='::', port=49189), raddr=(), status='LISTEN', pid=728),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49164), raddr=addr(ip='192.168.1.251', port=5761), status='ESTABLISHED', pid=1392),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=5767), raddr=(), status='NONE', pid=1392),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=53556), raddr=(), status='NONE', pid=5480),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49748), raddr=addr(ip='192.168.1.251', port=5761), status='ESTABLISHED', pid=1492),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=55000), raddr=(), status='LISTEN', pid=1900),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59286), raddr=addr(ip='192.168.1.252', port=7880), status='CLOSE_WAIT', pid=1664),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59296), raddr=addr(ip='192.168.1.137', port=10756), status='TIME_WAIT', pid=0),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59310), raddr=addr(ip='192.168.1.44', port=10762), status='TIME_WAIT', pid=0),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=56145), raddr=(), status='NONE', pid=2268),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=49159), raddr=(), status='LISTEN', pid=616),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59324), raddr=addr(ip='74.125.204.101', port=443), status='SYN_SENT', pid=2268),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=139), raddr=(), status='LISTEN', pid=4),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=500), raddr=(), status='NONE', pid=920),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=58759), raddr=(), status='LISTEN', pid=10496),
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=1, laddr=addr(ip='::', port=135), raddr=(), status='LISTEN', pid=936),
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=1, laddr=addr(ip='::', port=49168), raddr=(), status='LISTEN', pid=1780),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=6689), raddr=(), status='LISTEN', pid=1900),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49157), raddr=addr(ip='192.168.1.251', port=5773), status='ESTABLISHED', pid=4),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=18385), raddr=(), status='LISTEN', pid=1392),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59322), raddr=addr(ip='74.125.204.101', port=443), status='SYN_SENT', pid=2268),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=50930), raddr=addr(ip='127.0.0.1', port=50929), status='ESTABLISHED', pid=6560),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=7670), raddr=(), status='NONE', pid=468),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=61838), raddr=(), status='NONE', pid=1900),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=63342), raddr=(), status='LISTEN', pid=6560),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=49189), raddr=(), status='LISTEN', pid=728),
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=2, laddr=addr(ip='::', port=500), raddr=(), status='NONE', pid=920),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=49188), raddr=addr(ip='127.0.0.1', port=18385), status='ESTABLISHED', pid=2768),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49156), raddr=addr(ip='192.168.1.251', port=5772), status='ESTABLISHED', pid=4),
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=1, laddr=addr(ip='::', port=49160), raddr=(), status='LISTEN', pid=160),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=53550), raddr=(), status='NONE', pid=5480),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=49160), raddr=(), status='LISTEN', pid=160),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=50929), raddr=addr(ip='127.0.0.1', port=50930), status='ESTABLISHED', pid=6560),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=58760), raddr=(), status='LISTEN', pid=6560),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49165), raddr=addr(ip='192.168.1.251', port=5921), status='ESTABLISHED', pid=1392),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49152), raddr=addr(ip='192.168.1.251', port=5871), status='ESTABLISHED', pid=4),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=1234), raddr=(), status='NONE', pid=468),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=49161), raddr=(), status='LISTEN', pid=920),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=5217), raddr=(), status='NONE', pid=1672),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=50927), raddr=addr(ip='127.0.0.1', port=50928), status='ESTABLISHED', pid=6560),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49153), raddr=addr(ip='192.168.1.251', port=5871), status='ESTABLISHED', pid=4),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49229), raddr=addr(ip='171.8.242.114', port=80), status='CLOSE_WAIT', pid=1508),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=11517), raddr=(), status='NONE', pid=1672),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49184), raddr=addr(ip='192.168.1.251', port=5924), status='ESTABLISHED', pid=1392),
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=2, laddr=addr(ip='::', port=4500), raddr=(), status='NONE', pid=920),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='127.0.0.1', port=60073), raddr=(), status='NONE', pid=1492),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='0.0.0.0', port=135), raddr=(), status='LISTEN', pid=936),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59306), raddr=addr(ip='192.168.1.252', port=6688), status='TIME_WAIT', pid=0),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='127.0.0.1', port=6942), raddr=(), status='LISTEN', pid=6560),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49259), raddr=addr(ip='192.168.1.251', port=9330), status='ESTABLISHED', pid=3220),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59309), raddr=addr(ip='192.168.1.45', port=10765), status='TIME_WAIT', pid=0),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=59320), raddr=addr(ip='192.168.1.252', port=6688), status='TIME_WAIT', pid=0),
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=1, laddr=addr(ip='::', port=49159), raddr=(), status='LISTEN', pid=616),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49180), raddr=addr(ip='192.168.1.251', port=5769), status='ESTABLISHED', pid=1392),
sconn(fd=-1, family=<AddressFamily.AF_INET6: 23>, type=1, laddr=addr(ip='::', port=49171), raddr=(), status='LISTEN', pid=720),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49558), raddr=addr(ip='192.168.1.251', port=5761), status='ESTABLISHED', pid=2560),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='192.168.1.37', port=137), raddr=(), status='NONE', pid=4),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='0.0.0.0', port=7671), raddr=(), status='NONE', pid=468),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='127.0.0.1', port=48200), raddr=(), status='NONE', pid=2096),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='127.0.0.1', port=64209), raddr=(), status='NONE', pid=1672),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=2, laddr=addr(ip='192.168.1.37', port=138), raddr=(), status='NONE', pid=4),
sconn(fd=-1, family=<AddressFamily.AF_INET: 2>, type=1, laddr=addr(ip='192.168.1.37', port=49155), raddr=addr(ip='192.168.1.251', port=5772), status='ESTABLISHED', pid=4)]
'''
import psutil
# 获取进程信息
# 通过psutil可以获取到所有进程的详细信息
print(psutil.pids()) # 获取所有进程的id
'''
[0, 4, 452, 532, 608, 616, 656, 720, 728, 740, 832, 892, 936, 160, 552, 920, 1056, 1124,
1244, 1268, 1392, 1508, 1664, 1672, 1780, 1808, 1828, 1900, 2096, 2184, 2200, 2532, 2560,
2768, 3008, 3020, 2180, 468, 2488, 2588, 3176, 3220, 3496, 3952, 4072, 2472, 3168, 2268,
3748, 2980, 4856,1492, 5616, 5480, 5748, 6560, 6700, 6264, 6900, 10496, 10688, 11888, 13064, 11796]
'''
# 获取指定进程的ID
p = psutil.Process(pid=5748)
print(p.name()) # 进程名称
'''
TesService.exe
'''
print(p.exe()) # 进程的exe路径
'''
C:\Program Files (x86)\Common Files\Tencent\TesService\TesService.exe
'''
print(p.cwd()) # 进程工作目录
'''
C:\Windows\system32
'''
print(p.cmdline()) # 进程启动的命令行
'''
['C:\\Program Files (x86)\\Common Files\\Tencent\\TesService\\TesService.exe']
'''
print(p.ppid()) # 父进程id
'''
720
'''
print(p.parent()) # 父进程
'''
psutil.Process(pid=720, name='services.exe', started='14:08:39')
'''
print(p.children()) #子进程列表
'''
[]
'''
# 可以看出,每个父进程可以有多个子进程,但是每个子进程只能有一个父进程,正所谓一个人只有一个父亲(特殊情况除外),但可以有多个儿子
print(p.status()) # 进程状态
'''
running
'''
print(p.username()) # 进程用户名
'''
NT AUTHORITY\SYSTEM
'''
print(p.create_time()) #进程创建时间,获取的是一个时间戳
# 转化为正常时间
import time
print(time.strftime("%Y-%m-%d %X",time.localtime(p.create_time())))
'''
1529388766.0
2018-06-19 14:12:46
'''
try:
print(p.terminal()) # 进程终端,在windows上无法使用,windows上没有terminals的概念
except Exception as e:
print(e)
'''
'Process' object has no attribute 'terminal'
'''
print(p.cpu_times()) # 进程使用的cpu时间
'''
pcputimes(user=0.015600099999999999, system=0.015600099999999999, children_user=0.0, children_system=0.0)
'''
print(p.memory_info()) #进程所使用的内存
'''
pmem(rss=1609728, vms=1318912, num_page_faults=2210, peak_wset=5107712, wset=1609728, peak_paged_pool=71736, paged_pool=68632, peak_nonpaged_pool=8952, nonpaged_pool=7928, pagefile=1318912, peak_pagefile=1429504, private=1318912)
'''
print(p.open_files()) # 进程打开的文件
'''
[]
'''
print(p.connections()) #进程相关的网络连接
'''
[]
'''
print(p.num_threads()) #进程的线程数量,这个进程里开启了多少个线程
'''
5
'''
print(p.threads()) # 这个进程内的所有线程信息
'''
[pthread(id=5744, user_time=0.0, system_time=0.0),
pthread(id=3648, user_time=0.0, system_time=0.0),
pthread(id=3700, user_time=0.0, system_time=0.0),
pthread(id=732, user_time=0.015600099999999999, system_time=0.0),
pthread(id=1052, user_time=0.0, system_time=0.0)]
'''
print(p.environ()) #进程的环境变量
'''
{'ALLUSERSPROFILE': 'C:\\ProgramData',
'APPDATA': 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Roaming',
'COMMONPROGRAMFILES': 'C:\\Program Files (x86)\\Common Files',
'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files',
'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files',
'COMPUTERNAME': 'CC037',
'COMSPEC': 'C:\\Windows\\system32\\cmd.exe',
'FP_NO_HOST_CHECK': 'NO',
'LOCALAPPDATA': 'C:\\Windows\\system32\\config\\systemprofile\\AppData\\Local',
'NUMBER_OF_PROCESSORS': '4',
'OS': 'Windows_NT',
'PATH': 'C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Program Files (x86)\\NVIDIA Corporation\\PhysX\\Common;',
'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC',
'PROCESSOR_ARCHITECTURE': 'x86', 'PROCESSOR_ARCHITEW6432': 'AMD64',
'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 60 Stepping 3, GenuineIntel',
'PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '3c03',
'PROGRAMDATA': 'C:\\ProgramData',
'PROGRAMFILES': 'C:\\Program Files (x86)',
'PROGRAMFILES(X86)': 'C:\\Program Files (x86)',
'PROGRAMW6432': 'C:\\Program Files',
'PSMODULEPATH': 'C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\',
'PUBLIC': 'C:\\Users\\Public', 'SYSTEMDRIVE': 'C:',
'SYSTEMROOT': 'C:\\Windows',
'TEMP': 'C:\\Windows\\TEMP',
'TMP': 'C:\\Windows\\TEMP', 'USERDOMAIN': 'WORKGROUP',
'USERNAME': 'CC037$',
'USERPROFILE': 'C:\\Windows\\system32\\config\\systemprofile',
'WINDIR': 'C:\\Windows', 'WINDOWS_TRACING_FLAGS': '3',
'WINDOWS_TRACING_LOGFILE': 'C:\\BVTBin\\Tests\\installpackage\\csilogfile.log'}
'''
print(p.terminate()) # 结束进程,自己把自己结束掉
'''
None
'''
# 返回结果为None,这里无法看到现象。我现在使用的是pycharm,如果这里的p是pycharm的话,调用p.terminate(),那么pycharm会被强制关闭
# 此外psutil还提供了test()函数,可以模拟出ps命令的效果
psutil.test()
'''
USER PID %MEM VSZ RSS TTY START TIME COMMAND
SYSTEM 0 ? ? 24 ? 14:08 32:01 System Idle Process
SYSTEM 4 ? 112 68 ? 14:08 06:35 System
LOCAL SERV 160 0.1 21420 18196 ? 14:08 00:01 svchost.exe
SYSTEM 452 ? 540 480 ? 14:08 00:00 smss.exe
Administra 468 0.2 23716 24856 ? 14:08 05:41 WinScript.exe
SYSTEM 532 ? 2224 2504 ? 14:08 00:01 csrss.exe
SYSTEM 552 ? 4616 4272 ? 14:08 00:00 svchost.exe
SYSTEM 608 0.3 20692 37004 ? 14:08 02:04 csrss.exe
SYSTEM 616 ? 1792 1480 ? 14:08 00:00 wininit.exe
SYSTEM 656 0.1 15696 13572 ? 14:08 00:03 winlogon.exe
SYSTEM 720 0.1 4920 6692 ? 14:08 00:01 services.exe
SYSTEM 728 0.1 6236 11052 ? 14:08 00:04 lsass.exe
SYSTEM 740 ? 2540 2460 ? 14:08 00:00 lsm.exe
SYSTEM 832 0.1 5164 6372 ? 14:08 00:10 svchost.exe
SYSTEM 892 ? 3024 4596 ? 14:08 00:00 nvvsvc.exe
SYSTEM 920 0.2 22044 30436 ? 14:08 00:06 svchost.exe
NETWORK SE 936 ? 4476 5580 ? 14:08 00:00 svchost.exe
LOCAL SERV 1056 0.1 5372 10992 ? 14:08 00:00 svchost.exe
NETWORK SE 1124 0.1 18028 12960 ? 14:08 00:02 svchost.exe
SYSTEM 1244 0.1 10856 16628 ? 14:08 00:03 nvxdsync.exe
LOCAL SERV 1268 0.1 6112 6784 ? 14:08 00:00 svchost.exe
SYSTEM 1392 0.1 24632 17816 ? 14:08 02:43 knbclient.exe
Administra 1492 0.7 111988 83220 ? 14:11 00:01 knbmenu.exe
Administra 1508 0.1 12992 13456 ? 14:08 00:01 taskhost.exe
Administra 1664 ? 3404 3936 ? 14:08 00:00 RsABC.exe
Administra 1672 0.8 97084 102356 ? 14:08 00:42 explorer.exe
NETWORK SE 1780 ? 2424 2780 ? 14:08 00:00 svchost.exe
NETWORK SE 1808 ? 912 852 ? 14:08 00:00 Locator.exe
NETWORK SE 1828 0.1 6220 10116 ? 14:08 00:01 sppsvc.exe
Administra 1900 0.1 18748 18452 ? 14:08 02:21 RsClient.exe
Administra 2096 0.1 6652 10040 ? 14:08 00:10 NvBackend.exe
Administra 2180 ? 1548 1732 ? 14:08 00:00 RsClientHost.exe
Administra 2184 ? 2224 2648 ? 14:08 00:00 iusb3mon.exe
Administra 2200 ? 1936 2044 ? 14:08 00:00 dinotify.exe
Administra 2268 1.4 103508 180272 ? 14:08 09:06 hGwF.exe
Administra 2472 ? 29616 1260 ? 14:08 00:00 kpandaclient.exe
Administra 2488 0.1 5744 6748 ? 14:08 20:32 rdpclip.exe
Administra 2532 0.1 16792 15124 ? 14:08 00:00 kdesk.exe
Administra 2560 ? 8956 5996 ? 14:08 01:20 khardware.exe
Administra 2588 0.1 12664 14096 ? 14:08 00:00 pcaui.exe
Administra 2768 ? 3288 3312 ? 14:08 00:00 kwndfinder.exe
Administra 2980 ? 2564 3332 ? 14:09 00:00 shell64.exe
Administra 3008 ? 1900 2968 ? 14:08 00:00 msspiwin.exe
Administra 3020 0.1 5480 8336 ? 14:08 00:03 khardware64.exe
Administra 3168 ? 736 880 ? 14:08 00:44 tqmnre.exe
Administra 3176 0.1 15128 18004 ? 14:08 04:51 upnpcont.exe
Administra 3220 0.1 37616 15732 ? 14:08 00:29 kpandaclient.exe
Administra 3496 0.2 72996 27172 ? 14:08 00:16 svchost.exe
Administra 3748 5.5 484848 686616 ? 14:08 24:40 hGwF.exe
Administra 3952 ? 38148 1536 ? 14:08 00:01 kpandaclient.exe
Administra 4072 0.1 58344 18624 ? 14:08 02:46 kpandaclient.exe
Administra 4856 0.1 14160 10624 ? 14:10 02:39 iezxlnt.exe
Administra 5480 0.2 26092 19736 ? 14:12 00:13 GameLoader.exe
LOCAL SERV 5616 0.1 26496 13096 ? 14:12 00:02 PresentationFontCache.exe
Administra 6264 ? 1600 3804 ? 14:16 00:00 conhost.exe
Administra 6560 8.0 1000752 1000796 ? 14:16 30:50 pycharm64.exe
Administra 6700 ? 1612 2848 ? 14:16 00:02 fsnotifier64.exe
LOCAL SERV 6900 0.1 16760 16592 ? 16:03 04:21 audiodg.exe
Administra 10496 0.2 22440 29344 ? 18:24 00:00 python.exe
Administra 10688 ? 1584 3852 ? 18:24 00:00 conhost.exe
Administra 11888 0.3 40580 37724 ? 18:40 00:10 hGwF.exe
Administra 13256 0.1 9604 13936 ? 20:07 00:00 python.exe
Administra 13372 ? 1588 3836 ? 20:07 00:00 conhost.exe
Administra 13968 0.1 3644 10956 ? 20:06 00:00 taskmgr.exe
'''
# 和我们在windows的任务管理器上看到的是不是类似的呢?
python--cProfile,memory_profiler,psutil的更多相关文章
- Python监控服务器利器--psutil
Python监控服务器利器--psutil 服务器的监控通过安装一些常用的监控软件之外,有时也需要运行一些shell或Python脚本:shell下可以使用系统自带的ps/free/top/df等sh ...
- python获取系统信息psutil
python获取系统信息psutil:psutil获取系统cpu使用率的方法是cpu_percent(),其有两个参数,分别是interval和percpu,interval指定的是计算cpu使用率的 ...
- 15.python笔记之psutil模块
一.psutil模块 1. psutil是一个跨平台库(http://code.google.com/p/psutil/),能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等) ...
- python模块之psutil详解
一.psutil模块: 1.psutil是一个跨平台库(http://pythonhosted.org/psutil/)能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息 ...
- Python模块学习 - psutil
psutil模块介绍 psutil是一个开源切跨平台的库,其提供了便利的函数用来获取才做系统的信息,比如CPU,内存,磁盘,网络等.此外,psutil还可以用来进行进程管理,包括判断进程是否存在.获取 ...
- python cProfile分析程序性能
转自:http://xianglong.me/article/analysis-python-application-performance-using-cProfile/?utm_source=tu ...
- python的memory_profiler模块使用
本文主要介绍了python内存分析工具: memory_profiler,可以展示每一行代码执行所增加的内存,方便做内存调优和排除bug memory_profiler是第三方模块,需要安装才能使用 ...
- python模块之psutil
一.模块安装 1.简介 psutil是一个跨平台库(http://pythonhosted.org/psutil/)能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息. ...
- Python常用库-Psutil
背景 介绍一个处理进程的实用工具,这个是一个第三方库.应用主要有类似ps.cd.top,还有查看硬盘.内存使用情况等. 推荐的理由主要有 2 个,第一个是跨平台的,不管是OSX.Centos.Wind ...
随机推荐
- python面向对象三大特性
面向对象的三大特性: 封装.继承和多态 一.封装 封装,顾名思义就是将内容封装到某个地方,以后可以直接调用被封装到某处的内容. - 将内容封装到某处 - 从某处调用被封装的内容 第一步,将内容封装到某 ...
- RSA前端加密解密
技术交流群: 233513714 <html> <head> <title>JavaScript RSA Encryption</title> < ...
- python开发记录第一篇
1. 安装pyCharm,下载地址https://www.jetbrains.com/pycharm/ 2. 注册license,修改windwos系统hosts,文件路径为:C:\Windows\S ...
- ACE handle_timeout 事件重入
当多线程运行反应器事件时, 注意handle_timeout会重入,单独线程不存在下列问题! 1. 一个timer事件 // test_ace_timer.cpp : Defines the entr ...
- vue理解$nextTick
首先要明确: Vue 实现响应式并不是数据发生变化之后 DOM 立即变化,而是按一定的策略进行 DOM 的更新. $nextTick 是在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后使用 ...
- 有关ViewFlipper的使用及设置动画效果的讲解
说到左右滑动,其实实现左右滑动的方式很多,有ViewPaer,自定义实现Viewgroup,gallery等都可以达到这种效果.这里做下ViewFliper实现左右滑动的效果. 会用到以下的技术: 1 ...
- Pascal小游戏 井字棋
一个很经典的井字棋游戏 Pascal源码Chaobs奉上 注意:1.有的FP版本不支持汉语,将会出现乱码.2.别想赢电脑了,平手不错了. 井字过三关: program TicTacToe; uses ...
- sublime text基本配置备份
sublime text基本配置备份: // Settings in here override those in "Default/Preferences.sublime-settings ...
- Windows+Python 3.6环境下安装PyQt4
第一步:下载.whl,地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyqt4,这里可以下载不同的python版本对应的包. 第二步:选择一个目录,将下 ...
- Kotlin中when表达式的使用:超强的switch(KAD 13)
作者:Antonio Leiva 时间:Feb 23, 2017 原文链接:https://antonioleiva.com/when-expression-kotlin/ 在Java(特别是Java ...