#!/usr/bin/env python # -*- coding:utf-8 -*- import threading import queue import time """ 对照着武老师的课程自己跟着做了一个线程池,主要的思路就是把要执行的任务放进队列中 然后创建若干个线程不断地从队列中获取任务并执行 相对比low B 版的线程池有很大改进,姑且叫low A版吧。。。 """ Stop_Flag = object() class ThreadPool(object): def __init__(self,max_num): self.max_num = max_num #创建一个队列用于保存任务 self.queue = queue.Queue() #创建一个列表保存已经创建的线程 self.generate_list = [] #创建一个列表保存当前空闲的线程 self.free_list = [] #是否结束任务的标志 self.terminate_flag = False def run(self, func, args, callback=None): w = (func, args, callback,) self.queue.put(w) #把相关的参数放入队列当中 if len(self.generate_list)< self.max_num and len(self.free_list) == 0: self.generate() def generate(self): t = threading.Thread(target=self.call) t.start() def call(self): ####获取当前的线程对象,并添加到已创建线程的列表当中 current_thread = threading.current_thread() self.generate_list.append(current_thread) work = self.queue.get() #从队列中获取相关的任务信息 while work != Stop_Flag: func, args, callback = work try: ret = func(*args) except Exception as e: print(e) if callback: try: callback(ret) except Exception as ex: print(ex) ###上面为一个线程执行一次任务的完整流程,一旦线程创建之后,则不断地从队列中获取任务 ######在执行完一次任务和获取下一次任务的空当内,线程处于空闲状态 if self.terminate_flag: break else: self.free_list.append(current_thread) work = self.queue.get() self.free_list.append(current_thread) ##在开始时或者在循环过程中接收到Stop_Flag时,都会执行下面的语句 self.generate_list.remove(current_thread) def close(self): #当只是完成上面的代码的情况下,主进程不会立即结束, ^ ^ 因为这个时候并没有把Stop_Flag传入队列 for i in range(len(self.generate_list)): self.queue.put(Stop_Flag) def terminate(self): self.terminate_flag = True def do(i): # time.sleep(0.5) print(i) def c(): pass pool = ThreadPool(10) for i in range(50): pool.run(func=do, args=(i,)) pool.terminate() # pool.close()