关于测试代码用了多长时间,我们之前介绍了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. SVD在推荐系统中的应用详解以及算法推导

    SVD在推荐系统中的应用详解以及算法推导     出处http://blog.csdn.net/zhongkejingwang/article/details/43083603 前面文章SVD原理及推 ...

  2. 网易OpenStack部署运维实战

    OpenStack自2010年项目成立以来,已经有超过200个公司加入了 OpenStack 项目,目前参与 OpenStack 项目的开发人员有 17,000+,而且这些数字还在增加,作为一个开源的 ...

  3. 手动实现一个lazyMan

    这应该算一个经典的面试题了,就是一个关于流程控制的问题,要求如下 //实现一个LazyMan,可以按照以下方式调用: LazyMan("Hank")//输出: //Hi! This ...

  4. 使用pip命令报You are using pip version 9.0.3, however version 18.0 is available pip版本过期.解决方案

    使用pip命令安装或卸载第三方库时报You are using pip version 9.0.3, however version 18.0 is available.错误,一般情况下是pip版本过 ...

  5. linux ubuntu开启sshd

    which ssh #查看文件 sudo apt-get install ssh #安装ssh cd /etc/init.d #切换目录 ls -l | grep ssh #执行启动脚本 sudo s ...

  6. [译]8-spring bean的作用域

    在spring中使用<bean/>标签定义bean的时候,可以使用scope属性来定义bean的作用域.如果想要每次 从spring容器得到一个新创建的bean实例,可以指定scope=& ...

  7. Python全栈工程师(包、模块 的导入)

    ParisGabriel                每天坚持手写  一天一篇  决定坚持几年 为了梦想 为了信仰     Python人工智能从入门到精通 $ pip3 install tenso ...

  8. 1079 Total Sales of Supply Chain (25 分)(树的遍历)

    给出一颗销售供应的树,树根唯一.在树根处货物的价格为p,然后从根节点开始没往结点走一层,该层的货物价格将会在父节点的价格上增加r%.给出每个叶节点的货物量求出他们的价格之和 #include<b ...

  9. Spring Web MVC 笔记

    Spring Web MVC 流程 Dispatcher Servlet 这是一个前端分派 Servlet(前端控制器模式),外部所有的请求都会先到达这里,然后由其将请求分派给其他组件进行实际的处理. ...

  10. 推荐系统评测指标--准确率(Precision)和召回率(Recall)、F值(F-Measure)

    转自http://bookshadow.com/weblog/2014/06/10/precision-recall-f-measure/ 1,准确率和召回率是广泛应用于信息检索和统计学分类领域的两个 ...