我在 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相反。
