基于简单版创建类对象过多,现自定义高级版python线程池,代码如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
1 #高级线程池 2 import queue 3 import threading 4 import time 5 StopEvent = object() #全局变量当作取任务时的停止标志只要不是元组就可以 6 class ThreadPool(object): 7 def __init__(self,max_num): 8 self.q = queue.Queue() #创建无数个队列 9 self.max_num = max_num #线程池最大数10 self.generate_list = [] #创建的线程11 self.free_list = [] #空闲的线程12 self.terminal = False13 14 def run(self,func,args,callback=None):15 self.q.put((func,args,callback)) #添加任务组,任务放队列16 if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:#没空闲线程并且已创建的线程小于最大线程17 self.generate_thread()#创建线程18 def generate_thread(self):19 threading.Thread(target=self.call).start()20 def call(self): #一直队列取任务包执行21 current_thread = threading.currentThread #获取当前线程22 self.generate_list.append(current_thread) #把当前线程加到创建的线程列表23 event = self.q.get()#从列表取任务24 while event != StopEvent:#取得不是特殊数据类型,那取得就是任务25 func,args,callback = event #解任务包26 #以下是执行func函数27 status = True28 try:29 ret = func(args)#执行任务30 except Exception as e:31 ret = e32 status = False33 if callback == None:34 pass35 else:36 callback(status,ret)#执行回调函数37 if self.terminal:#False 改成True后移出generate_list 就把线程终止了,python回收垃圾机制会回收38 event = StopEvent39 else:#默认执行以下40 self.free_list.append(current_thread) #把当前线程加入到空闲线程列表41 event = self.q.get()#取任务42 self.free_list.remove(current_thread)#取到任务后从空闲线程列表移除一个线程43 44 else: #是StopEvent 也就是取得不是任务包45 self.generate_list.remove(current_thread) #不是任务,移除创建得线程列表等待python回收46 def terminate(self):#不获取任务包了,终止线程不清空队列47 self.terminal = True48 #等着获取任务得线程结束49 max_num = len(self.generate_list)50 while max_num:51 self.q.put(StopEvent)52 max_num -= 153 54 def close(self):#放StopEvent,55 generate_list_num = len(self.generate_list)56 while generate_list_num:57 self.q.put(StopEvent)58 generate_list_num -= 159 60 def work(i):61 62 print(i)63 pool = ThreadPool(10) #最大线程数是564 for i in range(50):65 pool.run(work,(i))66 time.sleep(0.01)67 pool.terminate()68 # pool.close()