Python之实现不同版本线程池
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()
执行结果如图


浙公网安备 33010602011771号