这段时间一直在做一个爬虫系统,用python和django实现。其中涉及到了多线程的问题,在后端使用一个全局的字典用来保存和识别已经运行的线程。但是觉得这样的实现不是不太舒服。于是想找到一个更好的实现,这就想到了线程池这个概念。

线程池的概念是什么?

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

根据IBM文档中的描述,我理解为线程池是一个存放很多线程的单位,同时还有一个对应的任务队列。整个执行过程其实就是使用线程池中已有有限的线程把任务队列中的任务做完。这样做的好处就是你不需要为每个任务都创建一个线程,因为当你创建第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页面来控制线程的启动和停止,而这个线程池看起来只是用来并发完任务的。不过我想虽然在控制线程方面没有作用,但是它的并发执行任务的作用还是蛮不错,或许可以用在爬网页的部分。

在进一步思考,或许我可以把WorkManager作为一个线程来运行,不过要怎么按需停止WorkManager内部线程池中线程的运行和停止呢。

----EOF-----

此文对我有价值,小额(无负担)赞助下^_^

python 线程池回收_python实现线程池相关推荐

  1. python异步线程算法应用_Python多线程----线程池以及线程实现异步任务

    了解异步编程 楼主在工作中遇到了以下问题,开发接口爬取数据代码完成之后要写入redis缓存,但是在写入缓存的过程花费2-3s,进行这样就大大影响了接口的性能,于是想到了使用异步存储. 传统的同步编程是 ...

  2. python线程回收_python之线程

    开启一个字处理软件进程,该进程肯定需要办不止一件事情,比如监听键盘输入,处理文字,定时自动将文字保存到硬盘,这三个任务操作的都是同一块数据,因而不能用多进程.只能在一个进程里并发地开启三个线程,如果是 ...

  3. python爬取天天基金_python多线程+代理池爬取天天基金网、股票数据过程解析

    简介 提到爬虫,大部分人都会想到使用Scrapy工具,但是仅仅停留在会使用的阶段.为了增加对爬虫机制的理解,我们可以手动实现多线程的爬虫过程,同时,引入IP代理池进行基本的反爬操作. 本次使用天天基金 ...

  4. python通过ip池爬_Python爬虫 | IP池的使用

    一.简介 爬虫中为什么需要使用代理 一些网站会有相应的反爬虫措施,例如很多网站会检测某一段时间某个IP的访问次数,如果访问频率太快以至于看起来不像正常访客,它可能就会禁止这个IP的访问.所以我们需要设 ...

  5. Linux系统编程---14(回收子线程,回收多个子线程,线程分离,杀死线程)

    回收子线程 pthread_join 函数 阻塞等待线程退出,获取线程退出状态 其作用,对应进程中 waitpid() 函数. int pthread_join (pthread_t thread,v ...

  6. C语言 线程的回收与子线程返回值的接收

    穿的参数为二级指针 需要用全局变量来返回子线程的返回值 // ..使用内存映射可以拷贝文件 /* 对原始文件进行内存映射 创建一个新文件 把新文件的数据拷贝映射到内存中 通过内存拷贝将第一个文件的内存 ...

  7. python线程池操作_Python mutiprocessing多线程池pool操作示例

    本文实例讲述了Python mutiprocessing多线程池pool操作.分享给大家供大家参考,具体如下: python - mutiprocessing 多线程 pool 脚本代码: root@ ...

  8. python线程池原理_Python定时器线程池原理详解

    这篇文章主要介绍了Python定时器线程池原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 定时器执行循环任务: 知识储备 Timer(int ...

  9. python并行计算进程池通信_Python使用进程池管理进程和进程间通信

    与线程池类似的是,如果程序需要启动多个进程,也可以使用进程池来管理进程.程序可以通过 multiprocessing 模块的 Pool() 函数创建进程池,进程池实际上是 multiprocessin ...

最新文章

  1. unity人物旋转移动代码_Unity3D研究院之脚本实现模型的平移与旋转(六)
  2. u盘循环冗余能修复吗_古董修复能修复吗?-恩平 - 商业服务
  3. ubuntu 12.04 clang 3.4 安装
  4. linux yum yum gem,CentOS 7 gem 安装fluentd
  5. PB做的史上最强的矢量图监控软件(什么组态软件与监控软件的核心都源于此原理)...
  6. 锐捷ap怎么设置_WiFi又不稳定?怎么办,看这里
  7. 【树莓派】更新系统镜像下载地址,可能是最简单粗暴的树莓派搭建个人网站教程...
  8. python3多线程异步爬虫_python3爬虫中多线程进行解锁操作实例
  9. 微信公众平台开发(76) 获取用户基本信息
  10. 记一次程序员在办公室里的“撕逼”经历
  11. 《CLR via C#》读书笔记 之 参数
  12. PPT优秀模板|7个技巧,让你的设计呈现更加完美
  13. P1012 拼数(水题)
  14. python调用nmap_Python调用nmap扫描网段主机信息生成xml
  15. CAD格式刷怎么用?CAD格式刷使用技巧
  16. 问题小结:解决Ubuntu18.04系统无法连接WIFI
  17. 应用层与HTTP协议
  18. 如何做一个讨厌的女人
  19. 浏览器设置跨域及允许携带cookie
  20. 【转】常用的隧道技术

热门文章

  1. 前端学习(529):等分布局存在间距得实现得解决方案
  2. 第二十六期:100 个网络基础知识普及,看完成半个网络高手
  3. java学习(86):Interage方法compareto,parseint,intvalue
  4. 实例61:python
  5. oracle中错位函数,Oracle中的一些函数
  6. html头部尾部分离组件引入(JQ)
  7. 论文阅读(2)--Picking Deep Filter Responses for Fine-grained Image Recognition
  8. python中的sorted是什么意思_python中sort与sorted区别
  9. docker构建oracle集群,docker 构建 oracle数据库 镜像-Go语言中文社区
  10. LeetCode Smallest Range