引出

首先需要了解的是threadpool 的用途,他更适合于用到一些大量的短任务合集,而非一些时间长的任务,换句话说,适合大量的CPU密集型短任务,那些消耗时间较长的IO密集型长任务适合用协程去解决。

目前,python 标准库(特指python2.X)中的threadpool模块是在 multiprocessing.pool.threadpool,或者multiprocessing.dummy.ThreadPool(dummy模块是针对threading 多线程的进一步封装)。该模块有个缺点就是在所有线程执行完之前无法强制退出。实现原理大同小异:实例化pool的时候会创建指定数目的线程,把task 传给一个task-queue,线程会读取task-queue 的task,没有就阻塞,读取到后就执行,并将结果交给一个result-queue。

除了标准库中的threadpool,还有一些使用比较多的threadpool,以下展开。

pip 中的 ThreadPool

安装简单:pip install threadpool
使用如下:

1
2
3
4
pool = ThreadPool(poolsize)   # 定义线程池,指定线程数量
requests = makeRequests(some_callable, list_of_args, callback) # 调用makeRequests创建了要开启多线程的函数,以及函数相关参数和回调函数
[pool.putRequest(req) for req in requests] # 所有要运行多线程的请求扔进线程池
pool.wait() # 等待所有线程完成后退出

原理类似,源码解读可以参考python——有一种线程池叫做自己写的线程池 ,该博客还给出了对其的一些优化。

自己定制 threadpool

根据需要的功能定制适合自己的threadpool 也是一种常见的手段,常用的功能比如:是否需要返回线程执行后的返回值,线程执行完之后销毁还是阻塞等等。以下为自己经常用的的一个比较简洁的threadpool,感谢@kaito-kidd提供,源码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# coding: utf8

"""
线程池,用于高效执行某些任务。
""" import Queue
import threading class Task(threading.Thread): """ 任务 """ def __init__(self, num, input_queue, output_queue, error_queue):
super(Task, self).__init__()
self.thread_name = "thread-%s" % num
self.input_queue = input_queue
self.output_queue = output_queue
self.error_queue = error_queue
self.deamon = True def run(self):
"""run
"""
while 1:
try:
func, args = self.input_queue.get(block=False)
except Queue.Empty:
print "%s finished!" % self.thread_name
break
try:
result = func(*args)
except Exception as exc:
self.error_queue.put((func.func_name, args, str(exc)))
else:
self.output_queue.put(result) class Pool(object): """ 线程池 """ def __init__(self, size):
self.input_queue = Queue.Queue()
self.output_queue = Queue.Queue()
self.error_queue = Queue.Queue()
self.tasks = [
Task(i, self.input_queue, self.output_queue,
self.error_queue) for i in range(size)
] def add_task(self, func, args):
"""添加单个任务
"""
if not isinstance(args, tuple):
raise TypeError("args must be tuple type!")
self.input_queue.put((func, args)) def add_tasks(self, tasks):
"""批量添加任务
"""
if not isinstance(tasks, list):
raise TypeError("tasks must be list type!")
for func, args in tasks:
self.add_task(func, args) def get_results(self):
"""获取执行结果集
"""
while not self.output_queue.empty():
print "Result: ", self.output_queue.get() def get_errors(self):
"""获取执行失败的结果集
"""
while not self.error_queue.empty():
func, args, error_info = self.error_queue.get()
print "Error: func: %s, args : %s, error_info : %s" \
% (func.func_name, args, error_info) def run(self):
"""执行
"""
for task in self.tasks:
task.start()
for task in self.tasks:
task.join() def test(i):
"""test """
result = i * 10
return result def main():
""" main """
pool = Pool(size=5)
pool.add_tasks([(test, (i,)) for i in range(100)])
pool.run() if __name__ == "__main__":
main()

阅读原文

python-- python threadpool 的前世今生的更多相关文章

  1. python --- Python中的callable 函数

    python --- Python中的callable 函数 转自: http://archive.cnblogs.com/a/1798319/ Python中的callable 函数 callabl ...

  2. Micro Python - Python for microcontrollers

    Micro Python - Python for microcontrollers MicroPython

  3. 从Scratch到Python——python turtle 一种比pygame更加简洁的实现

    从Scratch到Python--python turtle 一种比pygame更加简洁的实现 现在很多学校都开设了Scratch课程,学生可以利用Scratch创作丰富的作品,然而Scratch之后 ...

  4. 从Scratch到Python——Python生成二维码

    # Python利用pyqrcode模块生成二维码 import pyqrcode import sys number = pyqrcode.create('从Scratch到Python--Pyth ...

  5. [Python]Python 使用 for 循环的小例子

    [Python]Python 使用 for 循环的小例子: In [7]: for i in range(5): ...: print "xxxx" ...: print &quo ...

  6. [python]python 遍历一个list 的小例子:

    [python]python 遍历一个list 的小例子: mlist=["aaa","bbb","ccc"]for ss in enume ...

  7. [Python]Python日期格式和字符串格式相互转换

    由字符串格式转化为日期格式的函数为: datetime.datetime.strptime() 由日期格式转化为字符串格式的函数为: datetime.datetime.strftime() # en ...

  8. [python]Python 字典(Dictionary) update()方法

    update() 函数把字典dict2的键/值对更新到dict里.如果后面的键有重复的会覆盖前面的语法dict.update(dict2) dict = {'Name': 'Zara', 'Age': ...

  9. 『Python』 ThreadPool 线程池模板

    Python 的 简单多线程实现 用 dummy 模块 一句话就可以搞定,但需要对线程,队列做进一步的操作,最好自己写个线程池类来实现. Code: # coding:utf-8 # version: ...

  10. python 添加 threadpool

    操作系统: Ubuntu 10.04 python安装依赖的软件包: python 出现 ImportError: No module named ** 我这里出现了: ImportError: No ...

随机推荐

  1. nmap的使用方法

    0x01 Nmap 典型用途: 1.通过对设备或者防火墙的探测来审计它的安全性. 2.探测目标主机所开放的端口. 3.网络存储,网络映射,维护和资产管理.(这个有待深入) 4.通过识别新的服务器审计网 ...

  2. 洛谷P4180 【模板】严格次小生成树[BJWC2010] 题解

    虽然中途写的时候有点波折,但是最后一发A,还是有点爽. 这虽然是个模板题,但还是涉及到许多知识的= = 首先我们求出一个最小生成树,并且求出其边权和\(ans\).那么现在考虑加入其它的边,每次加入在 ...

  3. 字符流,字节流,属性集(Properties)

    字节输入流(InputStream) java.io.InputStream抽象类是表示字节输入流的所有类的超类.可以读取字节信息到内存中.它定义了字节输入流的基本共性功能方法. public voi ...

  4. KVM-安装windows

    硬盘.网卡选择vitio 虚拟机配置2个cd-rom,分别挂载系统iso与virtio-win 开始安装无法识别硬盘,加载光驱驱动 安装完成进入系统之后,设备管理器添加驱动,识别设备

  5. 201671030107 胡文艳 实验十四 团队项目评审&课程项目总结

    项目 内容 这个作业属于哪个课程 2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验十四 团队项目评审&课程学习总结 作业学习目标 1.掌握软件项目评审会议流程 ...

  6. 项目Beta冲刺(4/7)(追光的人)(2019.5.26)

    所属课程 软件工程1916 作业要求 Beta冲刺博客汇总 团队名称 追光的人 作业目标 描述Beta冲刺每日的scrum和PM报告两部分 队员学号 队员博客 221600219 小墨 https:/ ...

  7. wordpress去掉category的另一个方法

    今天ytkah的客户问wordpress网站一直去不掉分类url中的/category/,他说已经按ytkah之前的方法设置了还是不起作用,进入网站后台发现,他们的网站有安装yoast,然后就大概知道 ...

  8. applyMiddleware 沉思录

    let newStore = applyMiddleware(mid1, mid2, mid3, ...)(createStore)(reducer, null); 给({ getState, dis ...

  9. expr算术运算

    #!/bin/bash #expr MY_VAR1= MY_VAR2= #expr 是命令 MY_VAR3=`expr $MY_VAR1 + $MY_VAR2` MY_VAR4=`expr $MY_V ...

  10. kafka中的offset概念

    在 Kafka 中无论是 producer 往 topic 中写数据, 还是 consumer 从 topic 中读数据, 都避免不了和 offset 打交道, 关于 offset 主要有以下几个概念 ...