Skip to main content
 首页 » 编程设计

Python线程定时器

2025年05月04日15Free-Thinker

我在 python 中有以下脚本,每 X 秒调用一个函数创建一个新线程:

def function(): 
    threading.Timer(X, function).start() 
    do_something 
 
function() 

我的问题是,如果函数执行需要 2*X 秒怎么办?因为我正在使用线程,所以这应该不是问题,对吧?我将同时运行更多的函数“实例”,但是一旦每个实例都完成,它的线程就应该被销毁。谢谢

请您参考如下方法:

如果该函数需要 2*X 秒,那么您将同时运行多个 function 实例。举个例子很容易看出:

import threading 
import time 
 
X = 2 
 
def function(): 
    print("Thread {} starting.".format(threading.current_thread())) 
    threading.Timer(X, function).start() 
    time.sleep(2*X) 
    print("Thread {} done.".format(threading.current_thread())) 
 
function() 

输出:

Thread <_MainThread(MainThread, started 140115183785728)> starting. 
Thread <_Timer(Thread-1, started 140115158210304)> starting. 
Thread <_MainThread(MainThread, started 140115183785728)> done. 
Thread <_Timer(Thread-2, started 140115149817600)> starting. 
Thread <_Timer(Thread-3, started 140115141424896)> starting. 
Thread <_Timer(Thread-1, started 140115158210304)> done. 
Thread <_Timer(Thread-4, started 140115133032192)> starting. 
Thread <_Timer(Thread-2, started 140115149817600)> done. 
Thread <_Timer(Thread-3, started 140115141424896)> done. 
Thread <_Timer(Thread-5, started 140115158210304)> starting. 
Thread <_Timer(Thread-6, started 140115141424896)> starting. 
Thread <_Timer(Thread-4, started 140115133032192)> done. 
Thread <_Timer(Thread-7, started 140115149817600)> starting. 
Thread <_Timer(Thread-5, started 140115158210304)> done. 
Thread <_Timer(Thread-8, started 140115133032192)> starting. 
Thread <_Timer(Thread-6, started 140115141424896)> done. 
Thread <_Timer(Thread-9, started 140115158210304)> starting. 
Thread <_Timer(Thread-7, started 140115149817600)> done. 
Thread <_Timer(Thread-10, started 140115141424896)> starting. 
Thread <_Timer(Thread-8, started 140115133032192)> done. 
Thread <_Timer(Thread-11, started 140115149817600)> starting. 
<And on and on forever and ever> 

从输出结果可以看出,这也是一个无限循环,所以程序永远不会结束。

如果 function 的多个实例同时运行是安全的,那么这很好。如果不是,那么您需要使用锁来保护 function 的非线程安全部分:

import threading 
import time 
 
X = 2 
lock = threading.Lock() 
 
def function(): 
    with lock: 
        print("Thread {} starting.".format(threading.current_thread())) 
        threading.Timer(X, function).start() 
        time.sleep(2*X) 
        print("Thread {} done.".format(threading.current_thread())) 
 
function() 

输出:

Thread <_MainThread(MainThread, started 140619426387712)> starting. 
Thread <_MainThread(MainThread, started 140619426387712)> done. 
Thread <_Timer(Thread-1, started 140619400812288)> starting. 
Thread <_Timer(Thread-1, started 140619400812288)> done. 
Thread <_Timer(Thread-2, started 140619392419584)> starting. 
Thread <_Timer(Thread-2, started 140619392419584)> done. 
Thread <_Timer(Thread-3, started 140619381606144)> starting. 
Thread <_Timer(Thread-3, started 140619381606144)> done. 
Thread <_Timer(Thread-4, started 140619392419584)> starting. 
Thread <_Timer(Thread-4, started 140619392419584)> done. 
Thread <_Timer(Thread-5, started 140619381606144)> starting. 

最后一点:由于全局解释器锁,在 CPython 中,一次只能有一个线程实际执行字节码。因此,当您使用线程时,如果您正在执行受 CPU 限制的任务,那么您并没有真正提高性能,因为实际上每次只有一个线程在执行。相反,操作系统最终会在所有线程之间频繁切换,从而为每个线程分配一点 CPU 时间。这通常最终会比单线程方法慢,因为在线程之间切换会增加开销。如果您计划在每个线程中执行 CPU 密集型工作,您可能需要使用 multiprocessing相反。