1、利用queue和threading模块可以实现多个版本的线程池,这里先贴上一个简单的
import queue import time import threading class ThreadPool(object): def __init__(self,max_num = 20):#默认最大20个线程 self.queue=queue.Queue(max_num) for i in range(max_num):#将20个线程类名放进队列 self.queue.put(threading.Thread) def get_thread(self):#获取线程,没有的话会在这里等待 return self.queue.get() def add_thread(self):#添加线程 self.queue.put(threading.Thread) p = ThreadPool() def f1(p,args): time.sleep(1) print(args) p.add_thread()#函数执行完毕之后,自动添加线程回池 for i in range(100): ret=p.get_thread()#获得线程类名 t = ret(target=f1,args=(p,i))#准备启动线程 t.start()#启动线程
但是这个版本是一开始就创建了所有出线程池,浪费内存,线程也没有重复利用,下面的代理池解决了这个问题,有需要才创建,且重复利用空闲线程
2、高级版线程池
import queue import time import threading StopEvent = [] class ThreadPool(): def __init__(self,max_num): self.max_num = max_num#最多创建的线程数 self.generate_list = []#真实创建的线程数 self.free_list=[] self.q=queue.Queue() def run(self,func,args,callback=None): data = (func,args,callback)#将任务封装进一个元组 self.q.put(data)#将任务放进队列 if len(self.free_list) ==0 and len(self.generate_list) < self.max_num: self.work(data) def work(self,data): thread = threading.Thread(target=self.call)#创建线程 thread.start() def call(self): current_thread = threading.currentThread self.generate_list.append(current_thread)#把现有的线程添加进去 job = self.q.get()#去队列里面领取任务 while job != StopEvent: func, args, callback = job try:#执行任务 ret = func(args) except Exception as e: print(e) else:#如果有回调函数则执行 if callback: callback() else:pass self.free_list.append(current_thread)#任务执行完成则添加进空闲线程 job = self.q.get() self.free_list.remove(current_thread)#获得了任务则从空闲列表中去除 else: self.generate_list.remove(current_thread)#清除该线程,让Python垃圾回收机制处理 def close(self): for itme in range(len(self.generate_list)): self.q.put(StopEvent) def f1(args): #time.sleep(0.5) print(args) pool= ThreadPool(10) for i in range(50): pool.run(func=f1,args=(i,)) #time.sleep(5) print(len(pool.generate_list)) pool.close()
执行结果如图