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(自定义线程池 ...
随机推荐
- [已读]JavaScript DOM高级程序设计
08年出版,但是不得不说内容很好,正如书名,重点是DOM部分,看的还蛮早的,这本,记得是13年.
- 8593 最大覆盖问题 two pointer
8593 最大覆盖问题 时间限制:50MS 内存限制:1000K提交次数:193 通过次数:88 题型: 编程题 语言: G++;GCC;VC Description 输入格式 第1行是正整数n ...
- 前端之CSS盒模型介绍
css盒模型 css盒模型是css的基石,盒模型由content(主体内容),padding(补白,填充),border(边框),margin(外间距); 1.content: width:数值+单位 ...
- Warning: skipping non-radio button in group
Question: 最近在开发中,设计了一个对话框来进行一系列的设定,其中有一组Radio Buttons(单选按钮),但在Debug下,发现对话的弹出有点延迟,经过分析,确定是因为在对话框弹出之 ...
- Android 图片在SD卡及包下的存储
public class FileBitmap { /** * 获取sd卡中的bitmap,bitmap可见 * * @param bitmap * 读取bitmap的路径 * @return bit ...
- EJB2.0教程 详解EJB技术及实现原理
EJB是什么呢?EJB是一个J2EE体系中的组件.再简单的说它是一个能够远程调用的javaBean.它同普通的javaBean有两点不同.第一点,就是远程调用.第二点,就是事务的功能,我们在EJB中声 ...
- HDU 3377 Plan (插头DP,变形)
题意:有一个n*m的矩阵,每个格子中有一个值(可能负值),要从左上角走到右下角,求路径的最大花费. 思路: 除了起点和终点外,其他的点可以走,也可以不走. (2)我用的是括号表示法,所以起始状态为') ...
- 洛谷 P2068 统计和
题目描述 给定一个长度为n(n<=100000),初始值都为0的序列,x(x<=10000)次的修改某些位置上的数字,每次加上一个数,然后提出y (y<=10000)个问题,求每段区 ...
- 关于父类中的this指针的问题
在处理一个消息推送的问题的时候遇到个小问题,比如A是B的子类,当A生成实例时,会执行父类的构造函数,那么在父类中,this会是什么类型呢? 于是做了个小测试 子类ChildClass: public ...
- Python 学习日志9月19日
9月19日 周二 今天是普通的一天,昨天也是普通的一天,刚才我差点忘记写日志,突然想起来有个事情没做,回来写. 今天早晨学习<Head First HTML and CSS>第十一章节“布 ...