python第十一天-----补:线程池
低版本:
#!/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第十一天-----补:线程池的更多相关文章
- Python SSH爆破以及Python3线程池控制线程数
源自一个朋友的要求,他的要求是只爆破一个ip,结果出来后就停止,如果是爆破多个,完全没必要停止,等他跑完就好 #!usr/bin/env python #!coding=utf-8 __author_ ...
- Python之实现不同版本线程池
1.利用queue和threading模块可以实现多个版本的线程池,这里先贴上一个简单的 import queue import time import threading class ThreadP ...
- python第五课——自定义线程池
内容概要: 1.low版线程池 2.绝版线程池 1.low版线程池 设计思路:运用队列queue 将线程类名放入队列中,执行一个就拿一个出来 import queue import threading ...
- 并发编程(十一)—— Java 线程池 实现原理与源码深度解析(一)
史上最清晰的线程池源码分析 鼎鼎大名的线程池.不需要多说!!!!! 这篇博客深入分析 Java 中线程池的实现. 总览 下图是 java 线程池几个相关类的继承结构: 先简单说说这个继承结构,E ...
- Java并发(二十一):线程池实现原理
一.总览 线程池类ThreadPoolExecutor的相关类需要先了解: (图片来自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8% ...
- Python中为什么要使用线程池?如何使用线程池?
系统处理任务时,需要为每个请求创建和销毁对象.当有大量并发任务需要处理时,再使用传统的多线程就会造成大量的资源创建销毁导致服务器效率的下降.这时候,线程池就派上用场了.线程池技术为线程创建.销毁的开销 ...
- 《Windows核心编程系列》十一谈谈Windows线程池
Windows线程池 上一篇博文我们介绍了IO完成端口.得知IO完成端口可以非常智能的分派线程.但是IO完成端口仅对等待它的线程进行分派,创建和销毁线程的工作仍然需要我们自己来做. 我们自己也可以创建 ...
- Java并发编程的艺术(十一)——Executor与线程池
Executor框架简介 从JDK5开始,把工作单元和执行机制分离开来了,工作的单元包括Runnable和Callable,执行机制就是由Executor框架提供. Executor两级调度模型 Ho ...
- python第十一天-----补:缓存操作
memcached,首先下载python-memcached模块,在cmd中执行pip install python-memcached即可 memcached比较简单,默认情况仅支持简单的kv存储, ...
随机推荐
- 《Visual C++并行编程实战》译者序
说来凑巧,当开始着手这本书的翻译时,我刚刚入手了自己第一台四核计算机,而翻译工作临近完成之时,我又为自己添置了一台iPad 2(这是一台双核计算机).由此可见,多核计算机已经完全进入了我的日常生活.鉴 ...
- Sharepoint CAML 增删改查 List
Lists.UpdateListItems 方法 (websvcLists) Windows SharePoint Services 3 Adds, deletes, or updates the ...
- android管理联系人操作
ContentProvider扩展之管理系统联系人 我们都知道ContentProvider是用来共享数据的,然而android本身就提供了大量的ContentProvider,例如联系人信息,系统的 ...
- Oracle11g的delayed failed logins特性引起的性能问题
用户反映修改密码后程序明显变慢,查看AWR发现: ASH信息如下: 进一步验证: SQL>select event,p1 from v$session t where t.username is ...
- js计算日期之间的月份差
<script type="text/javascript"> getMonthBetween("2015-05-01","2016-05 ...
- Orcal学习
sqlplus有几种登陆方式 比如:1.C: > sqlplus "/as sysdba" --以操作系统权限认证的oracle sys管理员登陆2.C: > sqlp ...
- CSAPP(前言)
很久之前就听过有过CSAPP这本书的传闻了,今天终于决定上手这本神作:既然是神作,就要仔细拜读一下,今天看了一下前言部分还真的令人耳目一新,单单是前言部分就让我学习到几个新的知识点: 1.c和Java ...
- PowerDesigner里数据表里AUTO_INCREMENT(自增)的设置
使用流程: File->New Model->Model types->Physical Data Model->Physical Diagram 在下边DBMS里选择:MyS ...
- TODO Auto-generated method stub
在 菜单栏中 Window --> Preferences -->Java -->Code Style -->Code Templates--> Code --> ...
- 更改RAC日志组
alter database add logfile thread 1 group 5 ('+DATA/idb/onlinelog/group5.log') size 256m;alter datab ...