低版本:

 #!/usr/bin/env python
import threading
import time
import queue class TreadPool:
"""
将线程加入到队列中作为资源去完成任务
优点:简单好写容易理解
缺点:太尼玛多了.....
"""
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) def task(arg, p):
print(arg)
time.sleep(1)
p.add_thread() pool = TreadPool(5) for i in range(100):
t = pool.get_thread()
obj = t(target=task, args=(i, pool))
obj.start()

高级版本:

 #!/usr/bin/env python
# -*- coding:utf-8 -*- import queue # 队列模块
import threading # 线程模块
import contextlib # 上下文模块
import time # 时间模块 StopEvent = object() # 创建一个停止时所需要用到的对象 class ThreadPool(object):
"""
线程池(用于放置任务,将任务作为队列中元素让线程去取得,可以复用线程减少开销)
"""
def __init__(self, max_num, max_task_num=None):
"""
构造方法
:param max_num:
:param max_task_num:所创建的队列内最大支持的任务个数
"""
if max_task_num:
self.q = queue.Queue(max_task_num) # 指定队列任务数量则创建有限队列
else:
self.q = queue.Queue() # 未指定队列任务数量则创建无限队列
self.max_num = max_num # 每次使用的最大线程个数
self.cancel = False # 任务取消,默认False,用于线程停止的判断
self.terminal = False # 任务终止,默认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) # 调用线程类创建一个线程,参数传递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, arguments, callback = event # 任务具体函数,参数获取
try:
result = func(*arguments) # 结果为任务处理的出的结果
success = True # 任务处理成功
except Exception as e:
success = False # 任务处理失败
result = None # 结果为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 # 线程停止,判定条件变为真
full_size = len(self.generate_list) # 获取还有几个在执行任务的线程
while full_size: # 向队列中添加相应个数的空任务
self.q.put(StopEvent)
full_size -= 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) # 创建一个每次支持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): # 使用线程池执行30次任务
ret = pool.run(action, (i,), callback) time.sleep(1) # 1秒等待
print(len(pool.generate_list), len(pool.free_list)) # 打印线程池内当前任务个数及空任务个数
pool.close() # 线程停止
pool.terminate() # 线程池终止

python第十一天-----补:线程池的更多相关文章

  1. Python SSH爆破以及Python3线程池控制线程数

    源自一个朋友的要求,他的要求是只爆破一个ip,结果出来后就停止,如果是爆破多个,完全没必要停止,等他跑完就好 #!usr/bin/env python #!coding=utf-8 __author_ ...

  2. Python之实现不同版本线程池

    1.利用queue和threading模块可以实现多个版本的线程池,这里先贴上一个简单的 import queue import time import threading class ThreadP ...

  3. python第五课——自定义线程池

    内容概要: 1.low版线程池 2.绝版线程池 1.low版线程池 设计思路:运用队列queue 将线程类名放入队列中,执行一个就拿一个出来 import queue import threading ...

  4. 并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)

    史上最清晰的线程池源码分析 鼎鼎大名的线程池.不需要多说!!!!! 这篇博客深入分析 Java 中线程池的实现. 总览 下图是 java 线程池几个相关类的继承结构:    先简单说说这个继承结构,E ...

  5. Java并发(二十一):线程池实现原理

    一.总览 线程池类ThreadPoolExecutor的相关类需要先了解: (图片来自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8% ...

  6. Python中为什么要使用线程池?如何使用线程池?

    系统处理任务时,需要为每个请求创建和销毁对象.当有大量并发任务需要处理时,再使用传统的多线程就会造成大量的资源创建销毁导致服务器效率的下降.这时候,线程池就派上用场了.线程池技术为线程创建.销毁的开销 ...

  7. 《Windows核心编程系列》十一谈谈Windows线程池

    Windows线程池 上一篇博文我们介绍了IO完成端口.得知IO完成端口可以非常智能的分派线程.但是IO完成端口仅对等待它的线程进行分派,创建和销毁线程的工作仍然需要我们自己来做. 我们自己也可以创建 ...

  8. Java并发编程的艺术(十一)——Executor与线程池

    Executor框架简介 从JDK5开始,把工作单元和执行机制分离开来了,工作的单元包括Runnable和Callable,执行机制就是由Executor框架提供. Executor两级调度模型 Ho ...

  9. python第十一天-----补:缓存操作

    memcached,首先下载python-memcached模块,在cmd中执行pip install python-memcached即可 memcached比较简单,默认情况仅支持简单的kv存储, ...

随机推荐

  1. C++实现不能被继承的类——终结类 分类: C/C++ 2015-04-06 14:48 64人阅读 评论(0) 收藏

    1.       问题 C++如何实现不能被继承的类,即终结类.Java中有final关键字修饰,C#中有sealed关键字修饰,而C++目前还没有类似的关键字来修饰类实现终结类,需编程人员手动实现. ...

  2. [BZOJ 3530][Sdoi 2014]数数

    阿拉~好像最近总是做到 AC 自动机的题目呢喵~ 题目的算法似乎马上就能猜到的样子…… AC 自动机 + 数位 dp 先暴力转移出 f[i][j] :表示从 AC 自动机上第 j 号节点走 i 步且不 ...

  3. Docker registry V2

    部署私有Docker Registry 搭建 Insecure Registry 修改Registry server上的Docker daemon的配置,为DOCKER_OPTS增加–insecure ...

  4. mac10.9+php5.5.15+brew0.9.5的安装

      Brew 是 Mac 下面的包管理工具,通过 Github 托管适合 Mac 的编译配置以及 Patch,可以方便的安装开发工具. Mac 自带ruby 所以安装起来很方便,同时它也会自动把git ...

  5. MongoDB丢数据问题的分析

    坊间有很多传说MongoDB会丢数据.特别是最近有一个InfoQ翻译的Sven的一篇水文(为什么叫做水文?因为里面并没有他自己的原创,只是搜罗了一些网上的博客,炒了些冷饭吃),其中又提到了丢数据的事情 ...

  6. windows环境下局域网内无法访问apache站点

    DocumentRoot "D:/wamp/www/" <Directory />     AllowOverride none     order deny,allo ...

  7. 今天的工作发现了4年前的“bug一枚”

    上午的时候山东公司要求下拨资金160万(因目前系统不能支付个人卡),在下拨单保存的时候系统提示余额不足,我马上看内部存款,结果发现人家还有190万呢,然后就看今天的委托付款单还有下拨单,山东都没有,一 ...

  8. Asp.net MVC 视图引擎

    Asp.net MVC视图引擎有两种: 1.ASPX View Engine 这个做过WebForm的人都清楚 设计目标:一个用于呈现Web Form页面的输出的视图引擎. 2.Razor View ...

  9. 自动 点击切换 按钮切换 轮播无缝选项卡 ----原生js

    <!doctype html> <html> <head> <meta charset="utf-8"> <meta name ...

  10. xml 解析

    例:解析以下片段 <font> <name>Helvetica</name> <size units="pt">36</siz ...