关于测试代码用了多长时间,我们之前介绍了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的更多相关文章

  1. Python监控服务器利器--psutil

    Python监控服务器利器--psutil 服务器的监控通过安装一些常用的监控软件之外,有时也需要运行一些shell或Python脚本:shell下可以使用系统自带的ps/free/top/df等sh ...

  2. python获取系统信息psutil

    python获取系统信息psutil:psutil获取系统cpu使用率的方法是cpu_percent(),其有两个参数,分别是interval和percpu,interval指定的是计算cpu使用率的 ...

  3. 15.python笔记之psutil模块

    一.psutil模块 1. psutil是一个跨平台库(http://code.google.com/p/psutil/),能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等) ...

  4. python模块之psutil详解

    一.psutil模块: 1.psutil是一个跨平台库(http://pythonhosted.org/psutil/)能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息 ...

  5. Python模块学习 - psutil

    psutil模块介绍 psutil是一个开源切跨平台的库,其提供了便利的函数用来获取才做系统的信息,比如CPU,内存,磁盘,网络等.此外,psutil还可以用来进行进程管理,包括判断进程是否存在.获取 ...

  6. python cProfile分析程序性能

    转自:http://xianglong.me/article/analysis-python-application-performance-using-cProfile/?utm_source=tu ...

  7. python的memory_profiler模块使用

    本文主要介绍了python内存分析工具: memory_profiler,可以展示每一行代码执行所增加的内存,方便做内存调优和排除bug memory_profiler是第三方模块,需要安装才能使用 ...

  8. python模块之psutil

    一.模块安装 1.简介 psutil是一个跨平台库(http://pythonhosted.org/psutil/)能够轻松实现获取系统运行的进程和系统利用率(包括CPU.内存.磁盘.网络等)信息. ...

  9. Python常用库-Psutil

    背景 介绍一个处理进程的实用工具,这个是一个第三方库.应用主要有类似ps.cd.top,还有查看硬盘.内存使用情况等. 推荐的理由主要有 2 个,第一个是跨平台的,不管是OSX.Centos.Wind ...

随机推荐

  1. hihocoder1014 : Trie树

    #1014 : Trie树 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助, ...

  2. Service Intent must be explicit

    参考: http://blog.csdn.net/qs_csu/article/details/45114251 我做阿里云账号登录的时候,遇到一个问题,不知道阿里云服务的包名.怎么办?第二种方法可以 ...

  3. jQuery的.on方法

    jQuery on()方法是官方推荐的绑定事件的一个方法. $(selector).on(event,childSelector,data,function,map)由此扩展开来的几个以前常见的方法有 ...

  4. 剑指Offer - 九度1372 - 最大子向量和(连续子数组的最大和)

    剑指Offer - 九度1372 - 最大子向量和(连续子数组的最大和)2013-11-23 16:25 题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后, ...

  5. 运用Pascal来破坏DLL的一个实例

    运用Pascal来破坏DLL文件的一个实例 关于Pascal静态调用和动态的调用DLL的学习您可以看Delphi/Lazarus栏目. Uses Dos; {调用DOS库} Const Root='C ...

  6. 新生 & 语不惊人死不休 —— 《无限恐怖》读后有感

    开篇声明,我博客中“小心情”这一系列,全都是日记啊随笔啊什么乱七八糟的.如果一不小心点进来了,不妨直接关掉.我自己曾经写过一段时间的日记,常常翻看,毫无疑问我的文笔是很差的,而且心情也是瞬息万变的.因 ...

  7. Git上手:Git扫盲区

    Git 自述Git 是由伟大的电脑程序员Linus Torvalds编写的一个开源的,分布式的版本控制系统软件. Git 核心原理Git 利用底层数据结构,通过指向索引对象的可变指针,保存文件快照. ...

  8. JMeter学习笔记(九) 参数化1--函数助手:_CSVRead

    1.函数助手:_CSVRead 1)准备数据文件 ,文件可以是.csv格式,.dat格式,txt格式等 2)打开函数助手,生成参数 3)添加HTTP请求,引用参数 4)执行HTTP请求,察看结果树中的 ...

  9. python自动化运维篇

    1-1 Python运维-课程简介及基础 1-2 Python运维-自动化运维脚本编写 2-1 Python自动化运维-Ansible教程-Ansible介绍 2-2 Python自动化运维-Ansi ...

  10. Opencv3.0.0安装包

    这个资源是Opencv3.0.0安装包,包括Windows软件包,Android软件包,IOS软件包,还有opencv的源代码:需要的下载吧. 点击下载