您的位置:首页 > 理论基础 > 计算机网络

Python案例-网络编程-线程池

2016-07-23 08:45 615 查看

线程池:

python2.*没有真正的线程池,

python3.*功能不强,所以一般要么自己写,要么用第三方软件

以下举例两种自定义线程池代码

第一种:通过for循环配合队列来实现多线程

特点:

1、队列中存放线程;

2、线程使用完就关闭,然后重新创,不能被重复使用;

3、一旦开启程序,线程池就会开到最大上线;

#!/usr/bin/env python
# -- coding = 'utf-8' --
# Author Allen Lee
# Python Version 3.5.1
# OS Windows 7
import queue
import threading
import time
class ThreadPool:
def __init__(self,maxsize):
self.maxsize = maxsize
self._q = queue.Queue(maxsize)
for i in range(maxsize):
self._q.put(threading.Thread)
def get_thread(self):
return self._q.get()
def add_thread(self):
self._q.put(threading.Thread)

pool = ThreadPool(5)

def task(arg,p):
print(arg)
time.sleep(1)
p.add_thread

for i in range(100):
#threading.Thread类
t = pool.get_thread()
obj = t(target=task,args=(i,pool,))
obj.start()


第二种:稍复杂一些的

特点:

1、队列里存放任务;

2、任务分两种:a、真实任务;b、关闭信号;

3、根据当前任务量来创建线程;

4、线程可以重复使用;

#!/usr/bin/env python
# -- coding = 'utf-8' --
# Author Allen Lee
# Python Version 3.5.1
# OS Windows 7
import threading
import time
import queue
import contextlib

stoptarget = object()

#自建一个线程池类
class ThreadPool(object):
#在构造方法中创建队列,传递队列长度参数maxsize
def __init__(self,maxsize,maxtasklist=None):
if maxtasklist:
self.q = queue.Queue(maxtasklist)
else:
self.q = queue.Queue(maxsize)
self.maxsize = maxsize
#任务执行完正常退出的标签
self.Nclose = False
#不管是否执行完,都退出的标签
self.Iclose = False
#正在被使用的线程列表
self.inuse_list = []
#空闲线程列表
self.free_list = []

def run(self,task,args,callback=None):
"""
#task 任务函数
#args 函数参数
#callback 不论结果的回调函数,其有两个参数:1、执行状态;2、返回值,default=None,既不执行回调函数
#返回值,如果线程池结束,返回True or None
"""

#如何是线程池正常执行后关闭的,退出
if self.Nclose:
return
#如果没有可用线程,且在用线程小于线程池最大数量,则补充一个线程,其作用为监听当前线程池的线程数,放在执行程序里相当于守护进程
if len(self.free_list) == 0 and len(self.inuse_list) < self.maxsize:
self.inuse_thread()
obj = (task,args,callback,)
self.q.put(obj)

#创建线程方法
def inuse_thread(self):
opj = threading.Thread(target=self.call)
opj.start()

#循环获取线程的方法
def call(self):
current_thread = threading.currentThread
#在忙碌的线程列表中添加
self.inuse_list.append(current_thread)
#获取队列中信息
event = self.q.get()
#判断获取的消息是否为停止,如果不是,则获得读取消息中的task,args,callback 字段内容
while event != stoptarget:
task,args,callback = event
#异常判断,如果只选task成功,在将返回值赋给result,并置success 为True
try:
result = task(*args)
success = True
#如果异常则置于False和None
except Exception as f:
success = False
result = None
#如果回调函数不为空则将success和result返回给回调函数,否则不执行回调函数
if callback is not None:
try:
callback(success, result)
except Exception as f:
pass
with self.worker_state(self.free_list, current_thread):
#如任务异常退出,则给队列里输入stoptarget的消息
if self.Iclose:
event = stoptarget
#否则继续获取消息
else:
event = self.q.get()
else:
#将已经执行完的线程从忙碌线程列表中去掉
self.inuse_list.remove(current_thread)

#执行完所有的任务后,正常关闭
def Nclose(self):
self.Nclose = True
full_size = len(self.inuse_list)
while full_size:
self.q.put(stoptarget)
full_size -= 1

#无论是否还有任务,终止线程,此为异常关闭
def Iclose(self):
self.Iclose = True
while self.Iclose:
self.q.put(stoptarget)
self.q.empty()

#用于记录线程中正在等待的线程数,这里使用上下文模块的上下文管理方法处理之
@contextlib.contextmanager
def worker_state(self, state_list, worker_thread):
state_list.append(worker_thread)
#生成迭代器
try:
yield
finally:
state_list.remove(worker_thread)
#创建线程池为5个线程的对象
pool = ThreadPool(5)

#此为回调函数
def callback(status,result):
print(status,result)

#此为模拟的task
def action(i):
print(i)

#100个任务请求
for i in range(100):
t = pool.run(action,(i,),callback)

time.sleep(2)
print(len(pool.inuse_list), len(pool.free_list))
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息