python 五——自定义线程池
内容概要:
1.low版线程池
2.绝版线程池
1.low版线程池
设计思路:运用队列queue
将线程类名放入队列中,执行一个就拿一个出来
import queue
import threading class ThreadPool(object): def __init__(self, max_num=20):
self.queue = queue.Queue(max_num) #创建队列,最大数为20
for i in range(max_num):
self.queue.put(threading.Thread) #将类名放入队列中 def get_thread(self):
return self.queue.get() #从队列中取出类名 def add_thread(self):
self.queue.put(threading.Thread) #进类名放入队列中 def func(arg, p): #定义一个函数
print(arg)
import time
time.sleep(2)
p.add_thread() pool = ThreadPool(10) #创建对象,并执行该类的构造方法,即将线程的类名放入队列中 for i in range(30):
thread = pool.get_thread() #调用该对象的get_thread方法,取出类名
t = thread(target=func, args=(i, pool)) #创建对象,执行func,参数在args中
t.start()
由于此方法要求使用者修改原函数,并在原函数里传参数,且调用方法也发生了改变,并且有空闲线程浪费资源,实际操作中并不方便,故设计了下一版线程池。
2.绝版线程池
设计思路:运用队列queue
a.队列里面放任务
b.线程一次次去取任务,线程一空闲就去取任务
import queue
import threading
import contextlib
import time StopEvent = object() class ThreadPool(object): def __init__(self, max_num, max_task_num = None):
if max_task_num:
self.q = queue.Queue(max_task_num)
else:
self.q = queue.Queue()
self.max_num = max_num
self.cancel = False
self.terminal = False
self.generate_list = []
self.free_list = [] def run(self, func, args, callback=None):
"""
线程池执行一个任务
:param func: 任务函数
:param args: 任务函数所需参数
:param callback: 任务执行失败或成功后执行的回调函数,回调函数有两个参数1、任务函数执行状态;2、任务函数返回值(默认为None,即:不执行回调函数)
:return: 如果线程池已经终止,则返回True否则None
"""
if self.cancel:
return
if len(self.free_list) == 0 and len(self.generate_list) < self.max_num:
self.generate_thread()
w = (func, args, callback,)
self.q.put(w) def generate_thread(self):
"""
创建一个线程
"""
t = threading.Thread(target=self.call)
t.start() def call(self):
"""
循环去获取任务函数并执行任务函数
"""
current_thread = threading.currentThread()
self.generate_list.append(current_thread) event = self.q.get()
while event != StopEvent: func, args, callback = event
try:
result = func(*args)
success = True
except Exception as e:
success = False
result = None if callback is not None:
try:
callback(success, result)
except Exception as e:
pass with self.worker_state(self.free_list, current_thread):
if self.terminal:
event = StopEvent
else:
event = self.q.get()
else: self.generate_list.remove(current_thread) def close(self):
"""
执行完所有的任务后,所有线程停止
"""
self.cancel = True
count = len(self.generate_list)
while count:
self.q.put(StopEvent)
count -= 1 def terminate(self):
"""
无论是否还有任务,终止线程
"""
self.terminal = True while self.generate_list:
self.q.put(StopEvent) self.q.queue.clear() @contextlib.contextmanager
def worker_state(self, state_list, worker_thread):
"""
用于记录线程中正在等待的线程数
"""
state_list.append(worker_thread)
try:
yield
finally:
state_list.remove(worker_thread) # How to use pool = ThreadPool(5) def callback(status, result):
# status, execute action status
# result, execute action return value
pass def action(i):
print(i) for i in range(30):
ret = pool.run(action, (i,), callback) time.sleep(3)
print(len(pool.generate_list), len(pool.free_list))
print(len(pool.generate_list), len(pool.free_list))
pool.close()
# pool.terminate()
python 五——自定义线程池的更多相关文章
- 介绍开源的.net通信框架NetworkComms框架 源码分析(十五 ) CommsThreadPool自定义线程池
原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架 作者是英国人 以前是收费的 目前作者已经开源 许可是 ...
- java高并发编程(五)线程池
摘自马士兵java并发编程 一.认识Executor.ExecutorService.Callable.Executors /** * 认识Executor */ package yxxy.c_026 ...
- Executors提供的四种线程池和自定义线程池
JAVA并发编程——EXECUTORS 线程池的思想是一种对象池的思想,开放一块内存空间,里面存放了众多(未死亡)的线程,池中线程执行调度由池管理器来处理.当有线程任务时,从池中取一个,执行完毕,对象 ...
- python---基础知识回顾(十)进程和线程(py2中自定义线程池和py3中的线程池使用)
一:自定义线程池的实现 前戏: 在进行自定义线程池前,先了解下Queue队列 队列中可以存放基础数据类型,也可以存放类,对象等特殊数据类型 from queue import Queue class ...
- python day 20: 线程池与协程,多进程TCP服务器
目录 python day 20: 线程池与协程 2. 线程 3. 进程 4. 协程:gevent模块,又叫微线程 5. 扩展 6. 自定义线程池 7. 实现多进程TCP服务器 8. 实现多线程TCP ...
- Android线程管理之ThreadPoolExecutor自定义线程池
前言: 上篇主要介绍了使用线程池的好处以及ExecutorService接口,然后学习了通过Executors工厂类生成满足不同需求的简单线程池,但是有时候我们需要相对复杂的线程池的时候就需要我们自己 ...
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...
- Android 自定义线程池的实战
前言:在上一篇文章中我们讲到了AsyncTask的基本使用.AsyncTask的封装.AsyncTask 的串行/并行线程队列.自定义线程池.线程池的快速创建方式. 对线程池不了解的同学可以先看 An ...
- c#网络通信框架networkcomms内核解析之十 支持优先级的自定义线程池
NetworkComms网络通信框架序言 本例基于networkcomms2.3.1开源版本 gplv3协议 如果networkcomms是一顶皇冠,那么CommsThreadPool(自定义线程池 ...
随机推荐
- Spring MVC 入门实例报错404的解决方案
若启动服务器控制台报错,并且是未找到xml配置文件,初始化DispatchServlet失败,或者控制台未报错404,那么: 1.URL的排查: 格式-----------协议名://地址:端口号/上 ...
- Tame Your Software Dependencies for More Flexible Apps
http://msdn.microsoft.com/en-us/magazine/cc337885.aspx
- System.TypeInitializationException: 'The type initializer for 'MySql.Data.MySqlClient.Replication.ReplicationManager' threw an exception.'
下午在调试的时候报错数据库连接就报错我就很纳闷后面用原来的代码写发现还是报错 System.TypeInitializationException: 'The type initializer for ...
- 浅析ES6中的iterator
1.iterator迭代器必须保证其遍历终止条件可控,否则会形成死循环demo: //会用到iterator接口的场合 //1.for...of循环 //2. ...解构表达式 const obj = ...
- mysql同步出现1062错误
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;slave start;show slave status \G执行多次,直到不会出现1062错误为止 或者: my.cnf s ...
- IOS typedef 函数指针的用法
代码简化, 促进跨平台开发的目的. typedef 行为有点像 #define 宏,用其实际类型替代同义字. 不同点:typedef 在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换. 用 ...
- PHP-PHPExcel用法详解
以下文章来源:diandian_520 http://blog.csdn.net/diandian_520/article/details/7827038 1.header header(" ...
- vue+element ui项目总结点(四)零散细节概念巩固如vue父组件调用子组件的方法、拷贝数据、数组置空问题 等
vue config下面的index.js配置host: '0.0.0.0',共享ip (假设你的电脑启动了这个服务我电脑一样可以启动)-------------------------------- ...
- Servlet和JSP之自定义标签学习
此文章会讲述简单标签处理器,因为经典自定义标签处理器没有简单标签处理器方便使用,故在此不进行描述. 参考:慕课网的<JSP自定义标签>视频; <Servlet.JSP和Sprin ...
- vue2.0动画
相对于vue1.0来说,vue2.0的动画变化还是挺大的, 在1.0中,直接在元素中加 transition ,后面跟上名字. 而在vue2.0中,需要把设置动画的元素.路由放在<transit ...