python 的线程池主要有threadpool,不过它并不是内置的库,每次使用都需要安装,而且使用起来也不是那么好用,所以自己写了一个线程池实现,每次需要使用直接import即可。其中还可以根据传入的特征量handlerkey来获取每个任务的结果。

#!/bin/env python
# -*- coding:utf-8 -*- """
@lx
created on 2016-04-14
""" import Queue
import sys
import threading
import time
import StringIO
import traceback reload(sys)
sys.setdefaultencoding("utf8") class MyThread(threading.Thread):
"""Background thread connected to the requests/results queues."""
def __init__(self, workQueue, resultQueue, timeout=0.1, **kwds):
threading.Thread.__init__(self, **kwds)
self.setDaemon(True)
self._workQueue = workQueue
self._resultQueue = resultQueue
self._timeout = timeout
self._dismissed = threading.Event()
self.start() def run(self):
"""Repeatedly process the job queue until told to exit."""
while True:
if self._dismissed.isSet():
break handlerKey = None # unique key
code = 0 # callback return code
handlerRet = None
errMsg = "" try:
callable, args, kwds = self._workQueue.get(True, self._timeout)
except Queue.Empty:
continue
except:
exceptMsg = StringIO.StringIO()
traceback.print_exc(file=exceptMsg)
errMsg = exceptMsg.getvalue()
code = 3301 # system error
self._resultQueue.put(
(handlerKey, code, (callable, args, kwds), errMsg))
break if self._dismissed.isSet():
self._workQueue.put((callable, args, kwds))
break try:
if "handlerKey" in kwds:
handlerKey = kwds["handlerKey"]
handlerRet = callable(*args, **kwds) # block
self._resultQueue.put((handlerKey, code, handlerRet, errMsg))
except:
exceptMsg = StringIO.StringIO()
traceback.print_exc(file=exceptMsg)
errMsg = exceptMsg.getvalue()
code = 3303
self._resultQueue.put((handlerKey, code, handlerRet, errMsg)) def dismiss(self):
"""Sets a flag to tell the thread to exit when done with current job."""
self._dismissed.set() class ThreadPool(object):
def __init__(self, workerNums=3, timeout=0.1):
self._workerNums = workerNums
self._timeout = timeout
self._workQueue = Queue.Queue() # no maximum
self._resultQueue = Queue.Queue()
self.workers = []
self.dismissedWorkers = []
self._createWorkers(self._workerNums) def _createWorkers(self, workerNums):
"""Add num_workers worker threads to the pool."""
for i in range(workerNums):
worker = MyThread(self._workQueue, self._resultQueue,
timeout=self._timeout)
self.workers.append(worker) def _dismissWorkers(self, workerNums, _join=False):
"""Tell num_workers worker threads to quit after their current task."""
dismissList = []
for i in range(min(workerNums, len(self.workers))):
worker = self.workers.pop()
worker.dismiss()
dismissList.append(worker) if _join:
for worker in dismissList:
worker.join()
else:
self.dismissedWorkers.extend(dismissList) def _joinAllDissmissedWorkers(self):
"""
Perform Thread.join() on all
worker threads that have been dismissed.
"""
for worker in self.dismissedWorkers:
worker.join()
self.dismissedWorkers = [] def addJob(self, callable, *args, **kwds):
self._workQueue.put((callable, args, kwds)) def getResult(self, block=False, timeout=0.1):
try:
item = self._resultQueue.get(block, timeout)
return item
except Queue.Empty, e:
return None
except:
raise def waitForComplete(self, timeout=0.1):
"""
Last function. To dismiss all worker threads. Delete ThreadPool.
:param timeout
"""
while True:
workerNums = self._workQueue.qsize() # 释放掉所有线程
runWorkers = len(self.workers) if 0 == workerNums:
time.sleep(timeout) # waiting for thread to do job
self._dismissWorkers(runWorkers)
break
# if workerNums < runWorkers: # 不能这样子乱取消
# self._dismissWorkers(runWorkers - workerNums)
time.sleep(timeout)
self._joinAllDissmissedWorkers() if "__main__" == __name__:
test1 = """
def doSomething(*args, **kwds):
if "sleep" in kwds:
sleep = kwds["sleep"]
msgTxt = "sleep %fs.." % sleep
time.sleep(sleep)
return msgTxt for i in range(10):
print doSomething(sleep=0.1, handlerKey="key-%d"%i) wm = ThreadPool(10)
for i in range(10):
wm.addJob(doSomething, sleep=1, handlerKey="key-%d"%i)
wm.waitForComplete()
for i in range(10):
print wm.getResult()
del wm
"""
# test2 = """ def doSomething_(*args, **kwds):
sleep = int(args[0])
msgTxt = "sleep %ds.." % sleep
time.sleep(sleep)
return msgTxt wm = ThreadPool(10)
result = []
for i in range(10):
data = 5
wm.addJob(doSomething_, data) while 1:
res = wm.getResult()
if res:
result.append(res)
if 10 == len(result):
break
print "sleep 0.1"
time.sleep(0.1)
print time.time()
wm.waitForComplete()
print time.time()
# """

原创文章,转载请备注原文地址 http://www.cnblogs.com/lxmhhy/p/6032924.html

知识交流讨论请加qq群:180214441。谢谢合作

python线程池实现的更多相关文章

  1. 自定义高级版python线程池

    基于简单版创建类对象过多,现自定义高级版python线程池,代码如下 #高级线程池 import queue import threading import time StopEvent = obje ...

  2. 对Python线程池

    本文对Python线程池进行详细说明介绍,IDE选择及编码的解决方案进行了一番详细的描述,实为Python初学者必读的Python学习经验心得. AD: 干货来了,不要等!WOT2015 北京站演讲P ...

  3. Python 线程池(小节)

    Python 线程池(小节) from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor import os,time, ...

  4. python线程池ThreadPoolExecutor(上)(38)

    在前面的文章中我们已经介绍了很多关于python线程相关的知识点,比如 线程互斥锁Lock / 线程事件Event / 线程条件变量Condition 等等,而今天给大家讲解的是 线程池ThreadP ...

  5. python线程池及其原理和使用

    python线程池及其原理和使用 2019-05-29 17:05:20 whatday 阅读数 576 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互.在这种情形下,使用线程池可以很 ...

  6. python线程池示例

    使用with方式创建线程池,任务执行完毕之后,会自动关闭资源 , 否则就需要手动关闭线程池资源  import threading, time from concurrent.futures impo ...

  7. Python线程池与进程池

    Python线程池与进程池 前言 前面我们已经将线程并发编程与进程并行编程全部摸了个透,其实我第一次学习他们的时候感觉非常困难甚至是吃力.因为概念实在是太多了,各种锁,数据共享同步,各种方法等等让人十 ...

  8. 《转》python线程池

    线程池的概念是什么? 在IBM文档库中这样的一段描写:“在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是 如此,虚拟机将试图跟踪每一个对象 ...

  9. 一个简单的python线程池框架

    初学python,实现了一个简单的线程池框架,线程池中除Wokers(工作线程)外,还单独创建了一个日志线程,用于日志的输出.线程间采用Queue方式进行通信. 代码如下:(不足之处,还请高手指正) ...

随机推荐

  1. 6.Struts2简单类型数据的接受

    简单类型数据的接收 在Action类中定义与请求参数同名的属性, 即,要定义该属性的set方法,便能够使struts2自动接收请求参数并赋予同名属性. 简单类型数据的接受举例: 新建工程项目,名称为: ...

  2. [Web API] Web API 2 深入系列(5) 特性路由

    目录 1. 特性路由注册 2. 路由解析 - 生成DataTokens - 选择HttpController - 选择Action 特性路由的目的在于更好的提供restful架构的接口,最近好忙(懒) ...

  3. C#循环测试题

    关于如下程序结构的描述中,哪一项是正确的?   for ( ; ; ) { 循环体; //何问起   }   a) 不执行循环体b) 一直执行循环体,即死循环c) 执行循环体一次d) 程序不符合语法要 ...

  4. C#正则表达式通过HTML提取网页中的图片src

    目前在做HoverTreeCMS项目中有处理图片的部分,参考了一下网上案例,自己写了一个获取内容中的图片地址的方法. 可以先看看效果:http://tool.hovertree.com/a/zz/im ...

  5. 【转】c#获取网页地址参数

    假设当前页完整地址为:http://www.jbxue.com/aaa/bbb.aspx?id=5&name=kelli则: "http://"是协议名"www. ...

  6. python查找指定目录下所有文件,以及改文件名的方法

    一: os.listdir(path) 把path目录下的所有文件保存在列表中: >>> import os>>> import re>>> pa ...

  7. thinkphp配置文件路径

    thinkphp配置文件路径在入口文件index.php中配置. 如果Public目录在应用程序目录同等级位置: 2.如果Public在app内部则: 3.如果使用Public在app外部,但定义为: ...

  8. EC笔记,第二部分:6.若不想使用编译器默认生成的函数,就该明确拒绝

    6.若不想使用编译器默认生成的函数,就该明确拒绝 1.有的时候不希望对象被复制和赋值,那么就把复制构造函数与赋值运算符放在private:中,但是这两个函数是否需要实现呢?假设实现了,那么你的类成员方 ...

  9. 在DirectShow中支持DXVA 2.0(Supporting DXVA 2.0 in DirectShow)

    这几天在做dxva2硬件加速,找不到什么资料,翻译了一下微软的两篇相关文档.并准备记录一下用ffmpeg实现dxva2,将在第三篇写到.这是第二篇.,英文原址:https://msdn.microso ...

  10. 设计模式-装饰器模式(Decrator Model)

    文 / vincentzh 原文连接:http://www.cnblogs.com/vincentzh/p/6057666.html 目录 1.概述 2.目的 3.结构组成 4.实现 5.总结 1.概 ...