用Python实现一个简单的线程池


Posted in Python onApril 07, 2015

线程池的概念是什么?

在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是 如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些 很耗资源的对象创建和销毁。如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些"池化资源"技术产生的原因。

我理解为线程池是一个存放很多线程的单位,同时还有一个对应的任务队列。整个执行过程其实就是使用线程池中已有有限的线程把任务 队列中的任务做完。这样做的好处就是你不需要为每个任务都创建一个线程,因为当你创建第100个线程来执行第100个任务的时候,可能前面已经有50个线 程结束工作了。因此重复利用线程来执行任务,减少系统资源的开销。

一个不怎么恰当的比喻就是,有100台电脑主机箱需要从1楼搬到2楼,你不需要喊来100人帮忙搬,你只需要叫十个或者二十个人就足以,每个人分配十个或者五个甚至是谁搬的快谁就多搬知道完成未知。(这个比喻好像。。。。。)

不管如何吧,大体上理解了线程池的概念。那么怎么用python实现呢?

代码如下
 

# !/usr/bin/env python
# -*- coding:utf-8 -*-
# ref_blog:http://www.open-open.com/home/space-5679-do-blog-id-3247.html
import Queue
import threading
import time
class WorkManager(object):
  def __init__(self, work_num=1000,thread_num=2):
    self.work_queue = Queue.Queue()
    self.threads = []
    self.__init_work_queue(work_num)
    self.__init_thread_pool(thread_num)
  """
    初始化线程
  """
  def __init_thread_pool(self,thread_num):
    for i in range(thread_num):
      self.threads.append(Work(self.work_queue))
  """
    初始化工作队列
  """
  def __init_work_queue(self, jobs_num):
    for i in range(jobs_num):
      self.add_job(do_job, i)
  """
    添加一项工作入队
  """
  def add_job(self, func, *args):
    self.work_queue.put((func, list(args)))#任务入队,Queue内部实现了同步机制
  """
    检查剩余队列任务
  """
  def check_queue(self):
    return self.work_queue.qsize()
  """
    等待所有线程运行完毕
  """ 
  def wait_allcomplete(self):
    for item in self.threads:
      if item.isAlive():item.join()
class Work(threading.Thread):
  def __init__(self, work_queue):
    threading.Thread.__init__(self)
    self.work_queue = work_queue
    self.start()
  def run(self):
    #死循环,从而让创建的线程在一定条件下关闭退出
    while True:
      try:
        do, args = self.work_queue.get(block=False)#任务异步出队,Queue内部实现了同步机制
        do(args)
        self.work_queue.task_done()#通知系统任务完成
      except Exception,e:
        print str(e)
        break
#具体要做的任务
def do_job(args):
  print args
  time.sleep(0.1)#模拟处理时间
  print threading.current_thread(), list(args)
if __name__ == '__main__':
  start = time.time()
  work_manager = WorkManager(10, 2)#或者work_manager = WorkManager(10000, 20)
  work_manager.wait_allcomplete()
  end = time.time()
  print "cost all time: %s" % (end-start)

这个代码清晰易懂。

整个代码只有两个类:WorkManager和Work,前者确实如命名所示,是一个管理者,管理线程池和任务队列,而后者就是具体的一个线程。

它的整个运行逻辑就是,给WorkManager分配制定的任务量和线程数,然后每个线程都从任务队列中获取任务来执行,直到队列中没有任务。这里面也用到了Queue内部的同步机制(至于是啥同步机制目前还没去研究)。

总结一下这样一个线程池的作用,对于我本来的目的其实这个东西是永不上的,因为我需要在web页面来控制线程的启动和停止,而这个线程池看起来只是用来并发完任务的。不过我想虽然在控制线程方面没有作用,但是它的并发执行任务的作用还是蛮不错,或许可以用在爬网页的部分。

Python 相关文章推荐
跨平台python异步回调机制实现和使用方法
Nov 26 Python
python实现电子词典
Apr 23 Python
python字符串替换的2种方法
Nov 30 Python
简单的抓取淘宝图片的Python爬虫
Dec 25 Python
Python实现自动为照片添加日期并分类的方法
Sep 30 Python
Python 分发包中添加额外文件的方法
Aug 16 Python
python或C++读取指定文件夹下的所有图片
Aug 31 Python
python sqlite的Row对象操作示例
Sep 11 Python
python基于gevent实现并发下载器代码实例
Nov 01 Python
Python3 解决读取中文文件txt编码的问题
Dec 20 Python
opencv python如何实现图像二值化
Feb 03 Python
windows、linux下打包Python3程序详细方法
Mar 17 Python
浅谈Python程序与C++程序的联合使用
Apr 07 #Python
浅要分析Python程序与C程序的结合使用
Apr 07 #Python
python实现根据用户输入从电影网站获取影片信息的方法
Apr 07 #Python
python中列表元素连接方法join用法实例
Apr 07 #Python
简单介绍Python中的filter和lambda函数的使用
Apr 07 #Python
解析Python中的变量、引用、拷贝和作用域的问题
Apr 07 #Python
在Python中利用Pandas库处理大数据的简单介绍
Apr 07 #Python
You might like
php MySQL与分页效率
2008/06/04 PHP
浅析ThinkPHP中的pathinfo模式和URL重写
2014/01/06 PHP
mod_php、FastCGI、PHP-FPM等PHP运行方式对比
2015/07/02 PHP
thinkPHP模型初始化实例分析
2015/12/03 PHP
PHP如何使用Memcached
2016/04/05 PHP
php文件系统处理方法小结
2016/05/23 PHP
PHP输出图像imagegif、imagejpeg与imagepng函数用法分析
2016/11/14 PHP
php如何修改SESSION的生存存储时间的实例代码
2017/07/05 PHP
php+ajax实现仿百度查询下拉内容功能示例
2017/10/20 PHP
Aster vs KG BO3 第二场2.18
2021/03/10 DOTA
网页自动跳转代码收集
2009/09/27 Javascript
关于删除时的提示处理(确定删除吗)
2013/11/03 Javascript
jQuery实现鼠标可拖动调整表格列宽度
2014/05/26 Javascript
js HTML5 Canvas绘制转盘抽奖
2020/09/13 Javascript
Vue2 Vue-cli中使用Typescript的配置详解
2017/07/24 Javascript
vue单页应用中如何使用jquery的方法示例
2017/07/27 jQuery
Vue中的vue-resource示例详解
2018/11/02 Javascript
详解Vue-Router源码分析路由实现原理
2019/05/15 Javascript
Nuxt使用Vuex的方法示例
2019/09/06 Javascript
Python pip 安装与使用(安装、更新、删除)
2019/10/06 Python
关于python pycharm中输出的内容不全的解决办法
2020/01/10 Python
如何使用pandas读取txt文件中指定的列(有无标题)
2020/03/05 Python
Python内建序列通用操作6种实现方法
2020/03/26 Python
好的自荐信的要求
2013/10/30 职场文书
音乐专业自荐信
2014/02/07 职场文书
《诚实与信任》教学反思
2014/04/10 职场文书
学生安全承诺书
2014/05/22 职场文书
品酒会策划方案
2014/05/26 职场文书
领导干部考核评语
2015/01/04 职场文书
2015年端午节国旗下演讲稿
2015/03/19 职场文书
销售内勤岗位职责范本
2015/04/13 职场文书
2015年学校食堂工作总结
2015/04/22 职场文书
警示教育片观后感
2015/06/17 职场文书
Python max函数中key的用法及原理解析
2021/06/26 Python
Python集合的基础操作
2021/11/01 Python
如何解决goland,idea全局搜索快捷键失效问题
2022/04/03 Golang