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 ...
随机推荐
- hihocoder1014 : Trie树
#1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助, ...
- Service Intent must be explicit
参考: http://blog.csdn.net/qs_csu/article/details/45114251 我做阿里云账号登录的时候,遇到一个问题,不知道阿里云服务的包名.怎么办?第二种方法可以 ...
- jQuery的.on方法
jQuery on()方法是官方推荐的绑定事件的一个方法. $(selector).on(event,childSelector,data,function,map)由此扩展开来的几个以前常见的方法有 ...
- 剑指Offer - 九度1372 - 最大子向量和(连续子数组的最大和)
剑指Offer - 九度1372 - 最大子向量和(连续子数组的最大和)2013-11-23 16:25 题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后, ...
- 运用Pascal来破坏DLL的一个实例
运用Pascal来破坏DLL文件的一个实例 关于Pascal静态调用和动态的调用DLL的学习您可以看Delphi/Lazarus栏目. Uses Dos; {调用DOS库} Const Root='C ...
- 新生 & 语不惊人死不休 —— 《无限恐怖》读后有感
开篇声明,我博客中“小心情”这一系列,全都是日记啊随笔啊什么乱七八糟的.如果一不小心点进来了,不妨直接关掉.我自己曾经写过一段时间的日记,常常翻看,毫无疑问我的文笔是很差的,而且心情也是瞬息万变的.因 ...
- Git上手:Git扫盲区
Git 自述Git 是由伟大的电脑程序员Linus Torvalds编写的一个开源的,分布式的版本控制系统软件. Git 核心原理Git 利用底层数据结构,通过指向索引对象的可变指针,保存文件快照. ...
- JMeter学习笔记(九) 参数化1--函数助手:_CSVRead
1.函数助手:_CSVRead 1)准备数据文件 ,文件可以是.csv格式,.dat格式,txt格式等 2)打开函数助手,生成参数 3)添加HTTP请求,引用参数 4)执行HTTP请求,察看结果树中的 ...
- python自动化运维篇
1-1 Python运维-课程简介及基础 1-2 Python运维-自动化运维脚本编写 2-1 Python自动化运维-Ansible教程-Ansible介绍 2-2 Python自动化运维-Ansi ...
- Opencv3.0.0安装包
这个资源是Opencv3.0.0安装包,包括Windows软件包,Android软件包,IOS软件包,还有opencv的源代码:需要的下载吧. 点击下载