代码改变世界

小白成长之路:初识python(六) --python线程池

2017-11-07 20:10  张小贤TT  阅读(350)  评论(0编辑  收藏  举报
#!/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()