为了提高程序的效率,经常要用到多线程,尤其是IO等需要等待外部响应的部分。线程的创建、销毁和调度本身是有代价的,如果一个线程的任务相对简单,那这些时间和空间开销就不容忽视了,此时用线程池就是更好的选择,即创建一些线程然后反复利用它们,而不是在完成单个任务后就结束。

下面是用Python实现的通用的线程池代码:

view plainprint?
  1. import Queue, threading, sys
  2. from threading import Thread
  3. import time,urllib
  4. # working thread
  5. class Worker(Thread):
  6. worker_count = 0
  7. def __init__( self, workQueue, resultQueue, timeout = 0, **kwds):
  8. Thread.__init__( self, **kwds )
  9. self.id = Worker.worker_count
  10. Worker.worker_count += 1
  11. self.setDaemon( True )
  12. self.workQueue = workQueue
  13. self.resultQueue = resultQueue
  14. self.timeout = timeout
  15. def run( self ):
  16. ''' the get-some-work, do-some-work main loop of worker threads '''
  17. while True:
  18. try:
  19. callable, args, kwds = self.workQueue.get(timeout=self.timeout)
  20. res = callable(*args, **kwds)
  21. print "worker[%2d]: %s" % (self.id, str(res) )
  22. self.resultQueue.put( res )
  23. except Queue.Empty:
  24. break
  25. except :
  26. print 'worker[%2d]' % self.id, sys.exc_info()[:2]
  27. class WorkerManager:
  28. def __init__( self, num_of_workers=10, timeout = 1):
  29. self.workQueue = Queue.Queue()
  30. self.resultQueue = Queue.Queue()
  31. self.workers = []
  32. self.timeout = timeout
  33. self._recruitThreads( num_of_workers )
  34. def _recruitThreads( self, num_of_workers ):
  35. for i in range( num_of_workers ):
  36. worker = Worker( self.workQueue, self.resultQueue, self.timeout )
  37. self.workers.append(worker)
  38. def start(self):
  39. for w in self.workers:
  40. w.start()
  41. def wait_for_complete( self):
  42. # ...then, wait for each of them to terminate:
  43. while len(self.workers):
  44. worker = self.workers.pop()
  45. worker.join( )
  46. if worker.isAlive() and not self.workQueue.empty():
  47. self.workers.append( worker )
  48. print "All jobs are are completed."
  49. def add_job( self, callable, *args, **kwds ):
  50. self.workQueue.put( (callable, args, kwds) )
  51. def get_result( self, *args, **kwds ):
  52. return self.resultQueue.get( *args, **kwds )

Worker类是一个工作线程,不断地从workQueue队列中获取需要执行的任务,执行之,并将结果写入到resultQueue中,这里的workQueue和resultQueue都是现成安全的,其内部对各个线程的操作做了互斥。当从workQueue中获取任务超时,则线程结束。

WorkerManager负责初始化Worker线程,提供将任务加入队列和获取结果的接口,并能等待所有任务完成。

一个典型的测试例子如下,它用10个线程去下载一个固定页面的内容,实际应用时应该是执行不同的任务。

view plainprint?
  1. def test_job(id, sleep = 0.001 ):
  2. try:
  3. urllib.urlopen('https://www.gmail.com/').read()
  4. except:
  5. print '[%4d]' % id, sys.exc_info()[:2]
  6. return  id
  7. def test():
  8. import socket
  9. socket.setdefaulttimeout(10)
  10. print 'start testing'
  11. wm = WorkerManager(10)
  12. for i in range(500):
  13. wm.add_job( test_job, i, i*0.001 )
  14. wm.start()
  15. wm.wait_for_complete()
  16. print 'end testing'

转载于:https://blog.51cto.com/xmanmia/628331

用 Python 实现的线程池相关推荐

  1. python停止线程池_详解python中Threadpool线程池任务终止示例代码

    需求 加入我们需要处理一串个位数(0~9),奇数时需要循环打印它:偶数则等待对应时长并完成所有任务:0则是错误,但不需要终止任务,可以自定义一些处理. 关键点 定义func函数处理需求 callbac ...

  2. python ping利用线程池获取在线设备

    python ping获取一个VLAN在线设备 myPyPingDevice.py """=== coding: UTF8 ===""" # ...

  3. Python爬虫——使用线程池爬取同程旅行景点数据并做数据可视化

    大家好!我是霖hero 正所谓:有朋自远方来,不亦乐乎?有朋友来找我们玩,是一件很快乐的事情,那么我们要尽地主之谊,好好带朋友去玩耍!那么问题来了,什么时候去哪里玩最好呢,哪里玩的地方最多呢? 今天将 ...

  4. Python学习:线程池原理及实现

    传统多线程方案会使用"即时创建, 即时销毁"的策略.尽管与创建进程相比,创建线程的时间已经大大的缩短,但是如果提交给线程的任务是执行时间较短,而且执行次数极其频繁,那么服务器将处于 ...

  5. 【Python】实现线程池

    一.线程池代码解释 1.初始化函数__init__(): 2.线程池启动函数run(): 3.创建线程函数generate_thread(): 4.处理任务函数call(): 5.关闭线程函数clos ...

  6. Python爬虫_线程池实例——北京新发地菜价

    import requests import json import jsonpath from concurrent.futures import ThreadPoolExecutor print( ...

  7. python爬虫利用线程池下载视频

    由于requests模块中,requests.get()是线程阻塞的,所有当有多个爬虫进行爬取时,那么单线程式爬虫是耗时比较长的,所以我们需要使用线程池,利用线程池来爬取耗时比较长的资源,这里我们使用 ...

  8. 自定义简单版本python线程池

    python未提供线程池模块,在python3上用threading和queue模块自定义简单线程池,代码如下: 1 #用threading queue 做线程池 2 import queue 3 i ...

  9. Python 线程池 ThreadPoolExecutor(二) - Python零基础入门教程

    目录 一.Python 线程池前言 二.Python 线程池 ThreadPoolExecutor 常用函数 1.线程池 as_completed 函数使用 2.线程池 map 函数使用 3.线程池 ...

最新文章

  1. 揭秘一个操作灰色关键词牟取暴利的案例
  2. Nginx服务的信号控制
  3. 手机调试python的软件_Appium+Python(ios真机移动端App H5混合自动化实战测试)
  4. 今天的从上往下望去的企业即时通讯
  5. SpringBoot之Bean之条件注入@Condition
  6. 洛谷P1328生活大爆炸版石头剪刀布
  7. Source InSight context 窗口丢失的解决办法
  8. 一些常用jar包作用
  9. 微软面试题 麻将胡牌算法
  10. java 在线画布_使用canvas制作在线画板
  11. ENL3010 浪涌电流测试系统
  12. python微信红包代码_哄女朋友必备之微信自动发红包脚本(python+adb+androidviewclient)...
  13. 航旅纵横被质疑泄露用户数据;杭州网警破获67万台电脑数据遭黑客偷窃案;简历倒卖黑产:低至3毛一条,700元买采集器可无限量导数据...
  14. 基于python的马尔科夫链在股价预测中的应用(基于Tushare)
  15. 腾讯发布的开发语言安全指南:C/C++安全指南
  16. 基于TI C2540的OSAL UART流程分析
  17. linux协议栈网桥部分之cam表操作,linux协议栈之网桥实现之一
  18. PHP - 字符串 - 处理正反斜线 及 处理中文全角空格
  19. VB.Net程序设计:桌面彩色直尺
  20. 数据通信,数据网络和因特网

热门文章

  1. 《深入react技术栈》学习笔记(一)初入React世界
  2. shell 日志统计常用脚本
  3. LeetCode 93. 复原IP地址
  4. Android 第三章 SQLite 数据库
  5. spark SortShuffleWriter的实现
  6. mysql max_prepared_stmt_count_MySQL的max_prepared_stmt_count参数
  7. go generate介绍及使用
  8. golang高并发的理解
  9. 上传jar包到私服(仅限于翼支付公司工作流程使用)和涉及的技术总结
  10. 垃圾回收算法与实现系列-String在虚拟机中的实现