在Python中,我们可以通过threading
模块来创建并操作线程。但是线程的创建和销毁都需要一定的时间和资源,如果我们需要频繁的创建和销毁线程,就会造成性能的浪费。为了解决这一问题,Python提供了线程池的概念,即预先创建并初始化一定数量的线程,并维护一个任务队列,每当有任务需要执行时,将任务加入队列,由线程池中的线程来处理。
如果我们需要定时执行任务,可以使用Python中的定时器类Timer
,但是如果需要大量的定时任务,还是会遇到线程创建和销毁的问题。为了解决这一问题,可以使用Python中的ThreadPoolExecutor
和Timer
类来实现定时器线程池。
ThreadPoolExecutor
和Timer
实现定时器线程池ThreadPoolExecutor
是Python中一个用于并发执行任务的线程池实现,可以通过指定线程数量,创建一定数量的线程,并维护一个任务队列。当有新的任务需要执行时,任务将会被加入任务队列中,由空闲的线程来执行。在任务执行完毕后,线程将会返回线程池中,等待下一次任务的调度。
Timer
是Python中用于定时执行任务的类,可以指定一个时间间隔和要执行的函数或方法,当时间间隔到期后,将会自动执行对应的函数或方法。
我们可以结合ThreadPoolExecutor
和Timer
来实现定时器线程池。具体的实现步骤如下:
ThreadPoolExecutor
对象,指定线程数量。timers
,用于存放每个定时器对应的任务。add_timer
,用于添加定时器任务,函数参数包括定时器名称、时间间隔和要执行的函数。add_timer
函数中,创建一个Timer
对象,指定时间间隔和要执行的函数。然后将Timer
对象加入到字典timers
中,等待执行。run_timer
,用于定时执行任务。run_timer
函数中,遍历字典timers
,检查每个定时器是否已经过期,如果已经过期,则创建一个Future
对象,并加入到ThreadPoolExecutor
的任务队列中。然后将过期的定时器从字典timers
中移除。下面是实现代码:
import threading
from concurrent.futures import ThreadPoolExecutor
import time
class TimerThreadPool:
def __init__(self, thread_num=10):
self.timers = {}
self.executor = ThreadPoolExecutor(max_workers=thread_num)
def add_timer(self, name, interval, func):
timer = threading.Timer(interval, self.handle_timer, args=(name, func))
timer.start()
self.timers[name] = timer
def handle_timer(self, name, func):
fut = self.executor.submit(func)
self.timers.pop(name)
def run_timer(self):
while True:
time.sleep(1)
expired_timers = []
for timer_name in self.timers:
if not self.timers[timer_name].is_alive():
expired_timers.append(timer_name)
for timer_name in expired_timers:
self.handle_timer(timer_name, self.timers[timer_name].kwargs["func"])
tp = TimerThreadPool()
tp.add_timer("timer1", 2, lambda: print("timer1"))
tp.add_timer("timer2", 5, lambda: print("timer2"))
tp.run_timer()
上述代码创建了一个TimerThreadPool
类,使用ThreadPoolExecutor
来实现线程池,使用Timer
来实现定时器。在add_timer
方法中,我们将定时器加入到字典timers
中,等待执行。在handle_timer
方法中,我们创建一个Future
对象,并加入到线程池的任务队列中。在run_timer
方法中,我们循环遍历字典timers
,检查每个定时器是否已经过期,如果已经过期,则执行定时器对应的函数,并从字典timers
中移除。
示例输出:
timer1
timer2
timer1
timer1
timer1
timer2
timer1
timer1
timer1
timer1
可以看到,上述代码成功地按照设定的时间间隔执行了定时器任务。