面向对象开发中,大家知道创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。无节制的创建和销毁线程是一种极大的浪费。那我们可不可以把执行完任务的线程不销毁而重复利用呢?仿佛就是把这些线程放进一个池子,一方面我们可以控制同时工作的线程数量,一方面也避免了创建和销毁产生的开销。
线程在官方文档没有明确说明,但是是在multiprocessing 中给出了定义
from multiprocessing.pool import ThreadPool打印结果:
import threading,time
pool = ThreadPool(3);#定义一个线程池,线程池中有3个线程,等待调用
def double(n):
t = threading.currentThread()
time.sleep(1)
print('当前进程名:{},计算结果为{}'.format(t.name,n*2))
pool.map(double,range(5));
当前进程名:Thread-110,计算结果为2
当前进程名:Thread-112,计算结果为0
当前进程名:Thread-111,计算结果为4
当前进程名:Thread-110,计算结果为6
当前进程名:Thread-112,计算结果为8
下面我们自定义一个线程:
import threading, queue,time
def double(n):
return 2*n
class MyThread(threading.Thread):#自定义一个进程类
def __init__(self,queue):
super(MyThread,self).__init__()##先继续父类所有的属性
self._queue = queue# 用来存储傻
self.daemon = True# 进程必须是守护进程(进程完成后不会死掉)
self.start()#进程是要启动状态
def run(self):#重定义run函数
while 1:
f,args,kargs = self._queue.get()#f为函数,其它为参数
try:
print('using {}'.format(self._name))#打印进程名
print(f(*args,**kargs))
except Exception as e:
print(e)
self._queue.task_done() ## 任务完成,
class ThreadPool():##定义一俱个线程池
def __init__(self,size):
self._queue =queue.Queue(size)
for _ in range(size):#在进程池生成进程
MyThread(self._queue)
def add_task(self,f,*args,**kargs):
self._queue.put((f, args, kargs))#给进程执行任务
def wail_complete(self):
self._queue.join()#阻碍进程到其它进程全部完成
pool = ThreadPool(5)
for i in range(10):#给线程池中加了10个任务
pool.add_task(double,i)
time.sleep(0.5)
pool.wail_complete()
执行结果:
using Thread-121
0
using Thread-122
2
using Thread-123
4
using Thread-124
6
using Thread-125
8
using Thread-121
10
using Thread-122
12
using Thread-123
14
using Thread-124
16
using Thread-125
18
结果分析 :十个任务,用的始终是进程池中的五个进程