python线程池(转)
ThreadPool:
#! /usr/bin/env python
# -*- coding: utf-8 -*- import threadpool
import time def sayhello (a):
print("hello: "+a)
time.sleep(2) def main():
global result
seed=["a","b","c"]
start=time.time()
task_pool=threadpool.ThreadPool(5)
requests=threadpool.makeRequests(sayhello,seed)
for req in requests:
task_pool.putRequest(req)
task_pool.wait()
end=time.time()
time_m = end-start
print("time: "+str(time_m))
start1=time.time()
for each in seed:
sayhello(each)
end1=time.time()
print("time1: "+str(end1-start1)) if __name__ == '__main__':
main()
Futures:
#! /usr/bin/env python
# -*- coding: utf-8 -*- from concurrent.futures import ThreadPoolExecutor
import time def sayhello(a):
print("hello: "+a)
time.sleep(1) def main():
seed=["a","b","c","d","e","f"]
start1=time.time()
for each in seed:
sayhello(each)
end1=time.time()
print("time1: "+str(end1-start1))
start2=time.time()
with ThreadPoolExecutor(6) as executor:
for each in seed:
executor.submit(sayhello,each)
end2=time.time()
print("time2: "+str(end2-start2))
start3=time.time()
with ThreadPoolExecutor(6) as executor1:
executor1.map(sayhello,seed)
end3=time.time()
print("time3: "+str(end3-start3)) if __name__ == '__main__':
main()
重构 (在线程池运行时向里面添加新任务)
#! /usr/bin/env python
# -*- coding: utf-8 -*- import threading
import Queue
import hashlib
import logging
from utils.progress import PrintProgress
from utils.save import SaveToSqlite class ThreadPool(object):
def __init__(self, thread_num, args): self.args = args
self.work_queue = Queue.Queue()
self.save_queue = Queue.Queue()
self.threads = []
self.running = 0
self.failure = 0
self.success = 0
self.tasks = {}
self.thread_name = threading.current_thread().getName()
self.__init_thread_pool(thread_num) # 线程池初始化
def __init_thread_pool(self, thread_num):
# 下载线程
for i in range(thread_num):
self.threads.append(WorkThread(self))
# 打印进度信息线程
self.threads.append(PrintProgress(self))
# 保存线程
self.threads.append(SaveToSqlite(self, self.args.dbfile)) # 添加下载任务
def add_task(self, func, url, deep):
# 记录任务,判断是否已经下载过
url_hash = hashlib.new('md5', url.encode("utf8")).hexdigest()
if not url_hash in self.tasks:
self.tasks[url_hash] = url
self.work_queue.put((func, url, deep))
logging.info("{0} add task {1}".format(self.thread_name, url.encode("utf8"))) # 获取下载任务
def get_task(self):
# 从队列里取元素,如果block=True,则一直阻塞到有可用元素为止。
task = self.work_queue.get(block=False) return task def task_done(self):
# 表示队列中的某个元素已经执行完毕。
self.work_queue.task_done() # 开始任务
def start_task(self):
for item in self.threads:
item.start() logging.debug("Work start") def increase_success(self):
self.success += 1 def increase_failure(self):
self.failure += 1 def increase_running(self):
self.running += 1 def decrease_running(self):
self.running -= 1 def get_running(self):
return self.running # 打印执行信息
def get_progress_info(self):
progress_info = {}
progress_info['work_queue_number'] = self.work_queue.qsize()
progress_info['tasks_number'] = len(self.tasks)
progress_info['save_queue_number'] = self.save_queue.qsize()
progress_info['success'] = self.success
progress_info['failure'] = self.failure return progress_info def add_save_task(self, url, html):
self.save_queue.put((url, html)) def get_save_task(self):
save_task = self.save_queue.get(block=False) return save_task def wait_all_complete(self):
for item in self.threads:
if item.isAlive():
# join函数的意义,只有当前执行join函数的线程结束,程序才能接着执行下去
item.join() # WorkThread 继承自threading.Thread
class WorkThread(threading.Thread):
# 这里的thread_pool就是上面的ThreadPool类
def __init__(self, thread_pool):
threading.Thread.__init__(self)
self.thread_pool = thread_pool #定义线程功能方法,即,当thread_1,...,thread_n,调用start()之后,执行的操作。
def run(self):
print (threading.current_thread().getName())
while True:
try:
# get_task()获取从工作队列里获取当前正在下载的线程,格式为func,url,deep
do, url, deep = self.thread_pool.get_task()
self.thread_pool.increase_running() # 判断deep,是否获取新的链接
flag_get_new_link = True
if deep >= self.thread_pool.args.deep:
flag_get_new_link = False # 此处do为工作队列传过来的func,返回值为一个页面内容和这个页面上所有的新链接
html, new_link = do(url, self.thread_pool.args, flag_get_new_link) if html == '':
self.thread_pool.increase_failure()
else:
self.thread_pool.increase_success()
# html添加到待保存队列
self.thread_pool.add_save_task(url, html) # 添加新任务,即,将新页面上的不重复的链接加入工作队列。
if new_link:
for url in new_link:
self.thread_pool.add_task(do, url, deep + 1) self.thread_pool.decrease_running()
# self.thread_pool.task_done()
except Queue.Empty:
if self.thread_pool.get_running() <= 0:
break
except Exception, e:
self.thread_pool.decrease_running()
# print str(e)
break
python线程池(转)的更多相关文章
- 自定义高级版python线程池
基于简单版创建类对象过多,现自定义高级版python线程池,代码如下 #高级线程池 import queue import threading import time StopEvent = obje ...
- 对Python线程池
本文对Python线程池进行详细说明介绍,IDE选择及编码的解决方案进行了一番详细的描述,实为Python初学者必读的Python学习经验心得. AD: 干货来了,不要等!WOT2015 北京站演讲P ...
- Python 线程池(小节)
Python 线程池(小节) from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor import os,time, ...
- python线程池ThreadPoolExecutor(上)(38)
在前面的文章中我们已经介绍了很多关于python线程相关的知识点,比如 线程互斥锁Lock / 线程事件Event / 线程条件变量Condition 等等,而今天给大家讲解的是 线程池ThreadP ...
- python线程池及其原理和使用
python线程池及其原理和使用 2019-05-29 17:05:20 whatday 阅读数 576 系统启动一个新线程的成本是比较高的,因为它涉及与操作系统的交互.在这种情形下,使用线程池可以很 ...
- python线程池示例
使用with方式创建线程池,任务执行完毕之后,会自动关闭资源 , 否则就需要手动关闭线程池资源 import threading, time from concurrent.futures impo ...
- Python线程池与进程池
Python线程池与进程池 前言 前面我们已经将线程并发编程与进程并行编程全部摸了个透,其实我第一次学习他们的时候感觉非常困难甚至是吃力.因为概念实在是太多了,各种锁,数据共享同步,各种方法等等让人十 ...
- python线程池实现
python 的线程池主要有threadpool,不过它并不是内置的库,每次使用都需要安装,而且使用起来也不是那么好用,所以自己写了一个线程池实现,每次需要使用直接import即可.其中还可以根据传入 ...
- 《转》python线程池
线程池的概念是什么? 在IBM文档库中这样的一段描写:“在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是 如此,虚拟机将试图跟踪每一个对象 ...
- 一个简单的python线程池框架
初学python,实现了一个简单的线程池框架,线程池中除Wokers(工作线程)外,还单独创建了一个日志线程,用于日志的输出.线程间采用Queue方式进行通信. 代码如下:(不足之处,还请高手指正) ...
随机推荐
- java相关网址汇总2
分享几个高质量的技术博客和网站. 一.博客 0.酷壳 - COOLSHELL 博客地址是 https://coolshell.cn/. 这个博客的作者是技术圈基本无人不知的技术大牛,江湖人称耗子叔,网 ...
- 常见错误 RuntimeError: expected type torch.FloatTensor but got torch.cuda.FloatTensor
https://www.jianshu.com/p/0be7a375bdbe https://blog.csdn.net/qq_38410428/article/details/82973895 计算 ...
- phpstorm快捷键使用
- Docker那些事儿之编排工具docker-compose
前面已经讲解过docker的一些基础使用,镜像创建的操作过程,如果大量容器需要同时部署,一个一个容器进行服务器上的部署,估计要疯掉,在使用上我们需要找到更好更便捷的使用方式,今天要讲解的容器编排工具d ...
- UML类图介绍
一.概述 UML类图用来定义系统中的类,包括描述类的结构和类之间的关系.类图的主要作用于描述系统的静态结构. 类图的基本模型元素如下:
- MySQL查询去重
方法一: distinct select count(distinct CName) from Course 方法二: 使用分组 group by select count(1) from Cours ...
- sql的九个常用语句是什么
一.基础1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql server--- 创建 备份数 ...
- Greenplum 行存、列存,堆表、AO表的原理和选择
转载自: https://github.com/digoal/blog/blob/master/201708/20170818_02.md?spm=a2c4e.11153940.blogcont179 ...
- Ubuntu 下python开发环境的搭建
一.安装python3 ubuntu自身是安装python2的,例如在ubuntu 16.04中安装的就是python2.7.但我想在python3的环境下进行开发所以就要安装python3.但由于u ...
- 数据层面;MySQL查
AND 运算优先于OR运算执行(通过括号进行强化) count(*) 会得到包含NULL的数据行数:count(<列明>)会得到NULL之外的数据行数 SQL语句的总逻辑:书写顺序 sel ...