用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网络编程学习笔记(九):数据库客户端 DB-API
Jun 09 Python
python实现删除文件与目录的方法
Nov 10 Python
Python Queue模块详解
Nov 30 Python
Python中用于转换字母为小写的lower()方法使用简介
May 19 Python
python urllib urlopen()对象方法/代理的补充说明
Jun 29 Python
python中的迭代和可迭代对象代码示例
Dec 27 Python
python+django+sql学生信息管理后台开发
Jan 11 Python
Python处理命令行参数模块optpars用法实例分析
May 31 Python
numpy中三维数组中加入元素后的位置详解
Nov 28 Python
python numpy 矩阵堆叠实例
Jan 17 Python
解决Jupyter因卸载重装导致的问题修复
Apr 10 Python
python脚本使用阿里云slb对恶意攻击进行封堵的实现
Feb 04 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 adodb分页实现代码
2009/03/19 PHP
PHP+MySQL 手工注入语句大全 推荐
2009/10/30 PHP
AMFPHP php远程调用(RPC, Remote Procedure Call)工具 快速入门教程
2010/05/10 PHP
PHP合并数组+与array_merge的区别分析
2010/08/01 PHP
jquery使用hide方法隐藏指定id的元素
2015/03/30 Javascript
基于jQuery滑动杆实现购买日期选择效果
2015/09/15 Javascript
JavaScript面向对象之私有静态变量实例分析
2016/01/14 Javascript
详解如何使用webpack打包Vue工程
2017/05/27 Javascript
Vue与Node.js通过socket.io通信的示例代码
2018/07/25 Javascript
Vue中的v-for循环key属性注意事项小结
2018/08/12 Javascript
layerui代码控制tab选项卡,添加,关闭的实例
2019/09/04 Javascript
使用Easyui实现查询条件的后端传递并自动刷新表格的两种方法
2019/09/09 Javascript
一篇文章带你使用Typescript封装一个Vue组件(简单易懂)
2020/06/05 Javascript
详解Python 数据库 (sqlite3)应用
2016/12/07 Python
python中pika模块问题的深入探究
2018/10/13 Python
解决Python图形界面中设置尺寸的问题
2020/03/05 Python
什么是Python中的顺序表
2020/06/02 Python
python 图像插值 最近邻、双线性、双三次实例
2020/07/05 Python
从零开始的TensorFlow+VScode开发环境搭建的步骤(图文)
2020/08/31 Python
pandas 数据类型转换的实现
2020/12/29 Python
CSS3 三维变形实现立体方块特效源码
2016/12/15 HTML / CSS
Sneaker Studio匈牙利:购买运动鞋
2018/03/26 全球购物
上海奥佳笔试题面试题
2016/11/16 面试题
一道SQL面试题
2012/12/31 面试题
建筑设计师岗位职责
2013/11/18 职场文书
社区学习雷锋活动总结
2014/04/25 职场文书
师范毕业生求职信
2014/07/11 职场文书
教师个人考察材料
2014/12/16 职场文书
晚会开场白和结束语
2015/05/29 职场文书
手术室消毒隔离制度
2015/08/05 职场文书
2016年教师寒假学习心得体会
2015/10/09 职场文书
2016大学生求职自荐信范文
2016/01/28 职场文书
500字作文之周记
2019/12/13 职场文书
pytorch交叉熵损失函数的weight参数的使用
2021/05/24 Python
Jupyter Notebook内使用argparse报错的解决方案
2021/06/03 Python
Python内置包对JSON文件数据进行编码和解码
2022/04/12 Python