用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对小数进行除法运算的正确方法示例
Aug 25 Python
听歌识曲--用python实现一个音乐检索器的功能
Nov 15 Python
利用python生成一个导出数据库的bat脚本文件的方法
Dec 30 Python
python如何去除字符串中不想要的字符
Jul 05 Python
python绘制多个曲线的折线图
Mar 23 Python
Python2与Python3的区别实例分析
Apr 11 Python
浅析python 定时拆分备份 nginx 日志的方法
Apr 27 Python
python上selenium的弹框操作实现
Jul 13 Python
Django-Scrapy生成后端json接口的方法示例
Oct 06 Python
Django配置Bootstrap, js实现过程详解
Oct 13 Python
对PyTorch中inplace字段的全面理解
May 22 Python
python实现会员信息管理系统(List)
Mar 18 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 发送带附件邮件示例
2014/01/23 PHP
实现超用户体验 table排序javascript实现代码
2009/06/22 Javascript
jBox 2.3基于jquery的最新多功能对话框插件 常见使用问题解答
2011/11/10 Javascript
jQuery 下拉列表 二级联动插件分享
2012/03/29 Javascript
基于jquery插件实现常见的幻灯片效果
2013/11/01 Javascript
让JavaScript和其它资源并发下载的方法
2014/10/16 Javascript
深入理解JavaScript系列(19):求值策略(Evaluation strategy)详解
2015/03/05 Javascript
JavaScript获得当前网页来源页面(即上一页)的方法
2015/04/03 Javascript
浅谈javascript中关于日期和时间的基础知识
2016/07/13 Javascript
js时间比较 js计算时间差的简单实现方法
2016/08/26 Javascript
nodejs连接mongodb数据库实现增删改查
2016/12/01 NodeJs
node之本地服务器图片上传的方法示例
2019/03/26 Javascript
[50:11]2018DOTA2亚洲邀请赛 4.7总决赛 LGD vs Mineski 第三场
2018/04/09 DOTA
使用Python编写vim插件的简单示例
2015/04/17 Python
Python编程入门的一些基本知识
2015/05/13 Python
Linux下通过python访问MySQL、Oracle、SQL Server数据库的方法
2016/04/23 Python
详解Python3操作Mongodb简明易懂教程
2017/05/25 Python
Python编程实现控制cmd命令行显示颜色的方法示例
2017/08/14 Python
python判断设备是否联网的方法
2018/06/29 Python
python调用c++传递数组的实例
2019/02/13 Python
Python实现字典按key或者value进行排序操作示例【sorted】
2019/05/03 Python
Python实用库 PrettyTable 学习笔记
2019/08/06 Python
python+jinja2实现接口数据批量生成工具
2019/08/28 Python
Python for循环及基础用法详解
2019/11/08 Python
python实现滑雪游戏
2020/02/22 Python
澳大利亚婴儿、幼儿和儿童在线设计师商店:Smooch Baby
2019/02/16 全球购物
Pamela Love官网:纽约设计师Pamela Love的精美、时尚和穿孔珠宝
2020/10/19 全球购物
服装店营销方案
2014/03/10 职场文书
董事长秘书工作职责
2014/06/10 职场文书
清洁工岗位职责
2015/02/13 职场文书
村官2015年度工作总结
2015/10/14 职场文书
2019单位介绍信怎么写
2019/06/24 职场文书
Ajax是什么?Ajax高级用法之Axios技术
2021/04/21 Javascript
新手入门Mysql--sql执行过程
2021/06/20 MySQL
详解Nginx 被动检查服务器的存活状态
2021/10/16 Servers
nginx中proxy_pass各种用法详解
2021/11/07 Servers