多线程,实现对CPU、GPU状态的监控

多线程,实现对CPU、GPU状态的监控

一、获取代码运行时间

参考链接

import time
start=time.time()
#中间写上代码块
end=time.time()
print('Running time: %s Seconds'%(end-start))#单位是s

二、对CPU、GPU状态的监控

1、命令行:nvidia-smi,其中PID(Process Identification)指进程识别号。(关闭指定GPU进程用:kill -9 PID1 PID2 PIDn)
2、命令行:gpustat(相比于nvidia-smi显示更简洁),gpustat --help查看更多用法
上述两条命令配合watch命令(watch --help查看用法)都可以实时显示GUP运行状态,如watch -d -n 1 nvidia-smi/gpustat
3、通过以下代码(参考链接

import GPUtil
import time
import psutil

stopped_num = 10000000  #设置一个最大获取次数,防止记录文本爆炸
delay = 10  #采样信息时间间隔
Gpus = GPUtil.getGPUs()

def get_gpu_info():
    gpulist = []
    GPUtil.showUtilization()
    # 获取多个GPU的信息,存在列表里
    for gpu in Gpus:
        print('gpu.id:', gpu.id)
        print('GPU总量:', gpu.memoryTotal)
        print('GPU使用量:', gpu.memoryUsed)
        print('gpu使用占比:', gpu.memoryUtil * 100)
        # 按GPU逐个添加信息
        gpulist.append([ gpu.id, gpu.memoryTotal, gpu.memoryUsed,gpu.memoryUtil * 100])
    return gpulist

def get_cpu_info():
    ''' :return:
    memtotal: 总内存
    memfree: 空闲内存
    memused: Linux: total - free,已使用内存
    mempercent: 已使用内存占比
    cpu: 各个CPU使用占比
    '''
    mem = psutil.virtual_memory()
    memtotal = mem.total
    memfree = mem.free
    mempercent = mem.percent
    memused = mem.used
    cpu = psutil.cpu_percent(percpu=True)
    return memtotal, memfree, memused, mempercent, cpu

# 主函数
def main():
    times = 0
    while True:
        # 最大循环次数
        if times < stopped_num:
            # 打印当前时间
            time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
            # 获取CPU信息
            cpu_info = get_cpu_info()
            # 获取GPU信息
            gpu_info = get_gpu_info()
            # 添加时间间隙
            print(cpu_info)
            print(gpu_info,'\n')
            time.sleep(delay)
            times += 1
        else:
            break
            
if __name__ == '__main__':
    main()

三、多线程:threading模块的Thread类

a、核心要点

1、程序运行时默认就是在主线程上
2、通过实例化Thread类可以添加子线程,不同的线程同时处理不同的任务,这就是多线程编程
3、有两种方法可以添加子线程,如下:

b、第一种方法添加子线程:实例化Thread类

实例化Thread类。通过该实例对象的start()方法启动线程,线程抛出异常或执行完时自动退出。参考链接
(1)三条知识点:threading库中的Thread类的定义threading的属性和方法,Thread类的实例对象的属性和方法

1、threading库中的Thread类的定义
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None) 
参数名及含义:
target	线程调用的对象,就是目标函数
name	为线程起一个名字(线程的名字)
args	为目标函数传递实参,元组
kwargs	为目标函数传递关键字参数,字典

2、threading的属性和方法:
threading.current_thread()	     返回当前线程对象
threading.current_thread().ident 返回当前线程的id
threading.getident()			 返回当前线程的ID,非0整数
threading.main_thread()			 返回主线程(main线程)对象
threading.active_count()		 返回当前启动的且还未结束的线程个数
threading.enumerate()			 返回当前启动的且还未结束的线程列表

3、Thread类的实例对象的属性和方法
Thread.name	线程的名字,一个标识符,线程的名称可以重名。getName(),setName()获取、设置这个名词
Thread.ident	线程ID,是个非0的整数。线程启动后才会有ID,否则为None。线程退出,此时Id依旧可以访问。此ID会被系统重复使用
Thread.is_alive()	返回线程是否或者

(2)案例:通过实例化Thread类来添加子线程
注意:下面例子中,主进程、子线程t1、子线程t2同时在运行,所以可以看见运行结果在交替输出

import threading
import time
def worker1():
    print("子线程1开始")
    time.sleep(5)
    print("过了5s后,子线程1结束")
def worker2(x,y):
    print("{}+{}={}".format(x,y,x+y),threading.current_thread())
    print(threading.current_thread().ident)
    print(threading.get_ident())
    print(threading.main_thread())
    print(threading.active_count())
    print(threading.enumerate(), len(threading.enumerate()))
t1 = threading.Thread(target=worker1,name="t1") #实例化Thread类,创建第一个子线程
t1.start() #启动第一个子线程
t2 = threading.Thread(target=worker2,name="t2",args=(3,),kwargs={"y":15})#实例化Thread类,创建第二个子线程
t2.start()#启动第二个子线程
print(t2.name, t2.ident, t2.is_alive())
"""运行结果:
子线程1开始
3+15=18 <Thread(t2, started 140569273763584)>
注意输出的位置 t2 140569273763584 True
140569273763584
140569273763584
<_MainThread(MainThread, stopped 140569293787520)>
3
[<_MainThread(MainThread, stopped 140569293787520)>, <Thread(t1, started 140569282156288)>, <Thread(t2, started 140569273763584)>] 3
过了5s后,子线程1结束
"""

c、第二种方法添加子线程:自定义Thread的子类,重写run方法

通过继承Thread类来自定义一个Thread的子类,重写它的run方法。实例化该Thread子类,通过该对象的start()方法运行。(启动线程使用start()方法,该方法会自动调用run()方法,而run()方法用来运行函数)参考链接

import threading
import time
class worker1(threading.Thread):
    def run(self):
        print("子线程1开始")
        time.sleep(5)
        print("过了5s后,子线程1结束")
class worker2(threading.Thread):
    def run(self):
        print(threading.current_thread().ident)
        print(threading.get_ident())
        print(threading.main_thread())
        print(threading.active_count())
        print(threading.enumerate(), len(threading.enumerate()))

t1=worker1(name='t1')
t1.start()
t2=worker2(name='t2')
t2.start()
"""运行结果:
子线程1开始
140396349708032
140396349708032
<_MainThread(MainThread, started 140396369731968)>
3
[<_MainThread(MainThread, started 140396369731968)>, <worker1(t1, started 140396358100736)>, <worker2(t2, started 140396349708032)>] 3
过了5s后,子线程1结束
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值