跳转至

关于python的process_time和Thread_time

复现

  • 想对pyhton代码进行分析, 并进行有限的执行, 当某些代码超过我设定的时间运行的时候, 会执行我自定义的操作, 但是某些原因, 在检测 是否超时的时候, 我已开始使用的是time模块的process_time函数, 但是会出现一些问题

下面的代码, f1 和f2 最大的不同就是 f2 sleep了1秒钟, 虽然f2比f1晚执行了1s, 当然, 这并不会增加cpu的时间

import threading
import time

# 一个装饰器, 用来计算cpu使用时间
def wrapper_out(parameter):
    def wrapper(func):
        def inner(*args, **kwargs):
            pt = time.process_time()
            ret = func(*args, **kwargs)
            print(parameter, time.process_time() - pt)
            return ret
        return inner
    return wrapper


@wrapper_out("f1")
def f1(num):
    li = []
    for i in range(num):
        if i % 2 == 0:
            li.append(i)
        if i % 10:
            li.insert(-10000, i)
    return li


@wrapper_out("f2")
def f2(num):
    li = []
    for i in range(num):
        if i % 2 == 0:
            li.append(i)
        if i % 10:
            li.insert(-10000, i)

    time.sleep(1)  # f1 和 f2 最大的不同就是这里了
    return li


t1 = threading.Thread(target=f1, args=(50_0000, ))
t2 = threading.Thread(target=f2, args=(50_0000, ))

t1.setDaemon(False)
t2.setDaemon(False)

t1.start()
t2.start()
$ python3 demo.py
f1 3.450811
f2 3.466723

但是当我们修改t1 的执行次数之后, 使得f2在执行循环之后sleep的时候, f1由于是100w次循环所以f1还没停止运行仍然在密集计算

t1 = threading.Thread(target=f1, args=(100_0000, ))  # 执行100w次
t2 = threading.Thread(target=f2, args=(50_0000, ))
$ python3 demo.py
f2 4.4542660000000005
f1 5.021957

发现了吗, f2 的cpu使用时间, 竟然把sleep也算进去了!!

原因

python在使用process_time的时候, 是获取的当前进程已经使用的cpu的时间, 而不是当前线程

改进

使用 Thread_time 即可, 这个是获取 线程的cpu使用时间

import threading
import time

# 一个装饰器, 用来计算cpu使用时间
def wrapper_out(parameter):
    def wrapper(func):
        def inner(*args, **kwargs):
            pt = time.thread_time()
            ret = func(*args, **kwargs)
            print(parameter, time.thread_time() - pt)
            return ret
        return inner
    return wrapper


@wrapper_out("f1")
def f1(num):
    li = []
    for i in range(num):
        if i % 2 == 0:
            li.append(i)
        if i % 10:
            li.insert(-10000, i)
    return li


@wrapper_out("f2")
def f2(num):
    li = []
    for i in range(num):
        if i % 2 == 0:
            li.append(i)
        if i % 10:
            li.insert(-10000, i)

    time.sleep(1)  # f1 和 f2 最大的不同就是这里了
    return li


t1 = threading.Thread(target=f1, args=(50_0000, ))
t2 = threading.Thread(target=f2, args=(50_0000, ))

t1.setDaemon(False)
t2.setDaemon(False)

t1.start()
t2.start()
$ python3 demo.py
f1 1.6731393739999998
f2 1.683234348

正常了, 现在每个线程的cpu使用时间是分开计算的