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))
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- mongo实现消息队列
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例