python--profile,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的任务管理器上看到的是不是类似的呢?

猜你喜欢

转载自www.cnblogs.com/traditional/p/9200881.html