python实现线程池
线程池
简单线程池
import queue
import threading
import time class ThreadPool(object): #创建线程池类 def __init__(self, max_num=20): #创建一个最大长度为20的队列
self.queue = queue.Queue(max_num) #创建一个队列
for i in range(max_num): #循环把线程对象加入到队列中
self.queue.put(threading.Thread) #把线程的类名放进去,执行完这个Queue def get_thread(self): #定义方法从队列里获取线程
return self.queue.get() #在队列中获取值 def add_thread(self): #线程执行完任务后,在队列里添加线程
self.queue.put(threading.Thread) def func(pool,a1):
time.sleep(1)
print(a1)
pool.add_thread() #线程执行完任务后,队列里再加一个线程 p = ThreadPool(10) #执行init方法; 一次最多执行10个线程 for i in range(100):
thread = p.get_thread() #线程池10个线程,每一次循环拿走一个拿到类名,没有就等待
t = thread(target=func, args=(p, i,)) #创建线程; 线程执行func函数的这个任务;args是给函数传入参数
t.start() #激活线程
复杂线程池
线程池要点:
1,创建线程池时,是在需要执行线程的时候创建线程,而不是创建好最大队列等待执行
2,创建一个回调函数,检查出剩余队列的任务,当线程执行完函数的时候通知线程池,
3,使用线程池时让其循环获取任务,并执行
4,线程池,让其自行的去激活线程,执行完成后,关闭退出
import queue
import threading
import time
import contextlib StopEvent = object() class ThreadPool(object): def __init__(self, max_num):
self.q = queue.Queue() # 最多创建的线程数(线程池最大容量)
self.max_num = max_num self.terminal = False #如果为True 终止所有线程,不在获取新任务
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 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, arguments, callback = event #解开任务包; 分别取出值
try:
result = func(*arguments) #运行函数,把结果赋值给result
status = True #运行结果是否正常
except Exception as e:
status = False #表示运行不正常
result = e #结果为错误信息 if callback is not None: #是否存在回调函数
try:
callback(status, result) #执行回调函数
except Exception as e:
pass if self.terminal: # 默认为False,如果调用terminal方法
event = StopEvent #等于全局变量,表示停止信号
else:
# self.free_list.append(current_thread) #执行完毕任务,添加到闲置列表
# event = self.q.get() #获取任务
# self.free_list.remove(current_thread) # 获取到任务之后,从闲置列表中删除;不是元组,就不是任务
with self.worker_state(self.free_list, current_thread):
event = self.q.get() else:
self.generate_list.remove(current_thread) #如果收到终止信号,就从已经创建的线程列表中删除 def close(self): #终止线程
num = len(self.generate_list) #获取总共创建的线程数
while num:
self.q.put(StopEvent) #添加停止信号,有多少线程添加多少表示终止的信号
num -= 1 def terminate(self): #终止线程(清空队列) self.terminal = True #把默认的False更改成True while self.generate_list: #如果有已经创建线程存活
self.q.put(StopEvent) #有几个线程就发几个终止信号
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) def work(i):
print(i) pool = ThreadPool(10)
for item in range(50):
pool.run(func=work, args=(item,))
# 将任务放在队列中
# 着手开始处理任务
# - 创建线程
# - 有空闲线程,择不再创建线程
# - 不能高于线程池的限制
# - 根据任务个数判断
# - 线程去队列中取任务 pool.terminate()
详细参考:http://www.cnblogs.com/wupeiqi/articles/4839959.html
python实现线程池的更多相关文章
- Python的线程池实现
# -*- coding: utf-8 -*- #Python的线程池实现 import Queue import threading import sys import time import ur ...
- Python之路【第八篇】python实现线程池
线程池概念 什么是线程池?诸如web服务器.数据库服务器.文件服务器和邮件服务器等许多服务器应用都面向处理来自某些远程来源的大量短小的任务.构建服务器应用程序的一个过于简单的模型是:每当一个请求到达就 ...
- Python之线程池
版本一: #!/usr/bin/env python # -*- coding:utf-8 -*- import Queue import threading class ThreadPool(obj ...
- python自定义线程池
关于python的多线程,由与GIL的存在被广大群主所诟病,说python的多线程不是真正的多线程.但多线程处理IO密集的任务效率还是可以杠杠的. 我实现的这个线程池其实是根据银角的思路来实现的. 主 ...
- Python的线程池
#!/usr/bin/env python # -*- coding: utf-8 -*- """ concurrent 用于线程池和进程池编程而且更加容易,在Pytho ...
- [python] ThreadPoolExecutor线程池 python 线程池
初识 Python中已经有了threading模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍线程同步的信号量机制的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中创建了20个线程 ...
- 《Python》线程池、携程
一.线程池(concurrent.futures模块) #1 介绍 concurrent.futures模块提供了高度封装的异步调用接口 ThreadPoolExecutor:线程池,提供异步调用 P ...
- [python] ThreadPoolExecutor线程池
初识 Python中已经有了threading模块,为什么还需要线程池呢,线程池又是什么东西呢?在介绍线程同步的信号量机制的时候,举得例子是爬虫的例子,需要控制同时爬取的线程数,例子中创建了20个线程 ...
- python 绝版线程池
2.绝版线程池设计思路:运用队列queue a.队列里面放任务 b.线程一次次去取任务,线程一空闲就去取任务 import queueimport threadingimport contextlib ...
随机推荐
- ORA-12519, TNS:no appropriate service handler found
解决问题: 有时候连不上数据库是因为连接数到了极限了. select count(*) from v$process --当前的连接数 130 select value from v$paramete ...
- Hive(四):c#通过odbc访问hive
hive odbc 驱动配置成功后,通过c#访问就变得比较简单了,分为查询与更新操作,直接附上测试代码.在此过程中需要注意c#工程编译的目标平台 读写访问代码示例: public class Hive ...
- LintCode "Post Office Problem" !!!
* Non-intuitive state design class Solution { public: /** * @param A an integer array * @param k an ...
- bzoj2589: Spoj 10707 Count on a tree II
Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v),你需要回答u xor lastans和v这两个节点间有多少种不同的点权.其中lastans是上一个询问的答案,初 ...
- Python 创建和发布安装函数模块
1. create dir "nester" under C:\Users\eric\AppData\Local\Programs\Python\Python35-32\ 2. c ...
- Linux命令详解nice
[命令]nice — 调整程序运行的优先级 [格式]nice [OPTION] [command [arguments...]] [说明] 在当前程序运行优先级基础之上调整指定值得到新的程序运行优先级 ...
- TCP非阻塞通信
一.SelectableChannel SelectableChannel支持阻塞和非阻塞模式的channel 非阻塞模式下的SelectableChannel,读写不会阻塞 SelectableCh ...
- C#学习笔记三: C#2.0泛型 可控类型 匿名方法和迭代器
前言 C#1.0的委托特性使方法作为其他方法的参数来传递,而C#2.0 中提出的泛型特性则使类型可以被参数化,从而不必再为不同的类型提供特殊版本的实现方法.另外C#2.0还提出了可空类型,匿名方法和迭 ...
- jquery.cookie.js存与取以及过期时间设置
$(function(){ $(".active_out .abtn").click(function(){ $(this).parents(".active_out&q ...
- ActionScript 3.0 编程精髓 示例源码下载
根据书籍介绍(http://product.china-pub.com/38852#qy)的指引,找到了下载地址:http://moock.org/eas3/examples/