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方式进行通信. 代码如下:(不足之处,还请高手指正) ...
随机推荐
- rabbitmq数据备份与还原
一.场景 现在有服务器A和服务器B ,由于业务需要,要求把服务器A上mq的数据迁移到服务器B上,rabbitmq的数据包括元数据(RabbitMQ用户.vhost.队列.交换和绑定)和消息数据,而消息 ...
- Helix QAC — 软件静态测试工具
Helix QAC 是Perforce 公司(原PRQA 公司)产品,主要用于C/C++ 代码的完全自动化静态分析工作,可以提供编码规则检查.代码质量度量.软件结构分析.测试结果管理等功能.Helix ...
- PAT1025
这道题是照着晴神的来敲,但是自己技术太渣,中间还是出现了不少问题. 1.学习到排序的做法,利用algorithm库的sort(begin,end,cmp),自己按照题目要求来完成cmp的编写 可能经常 ...
- [原创]extjs htmleditor增加截图快速粘贴功能 插件
因客户需求,需要QQ截图后,能直接粘贴到htmleditor编辑器中,不要保存本地文件再上传,再插入到编辑器,太过麻烦. 常规做法:QQ截图-->选择保存路径-->确定保存文件--> ...
- Mysql 安装,及其闪退的问题解决
1.下载 Mysql 64下载链接(华军软件) http://soft.onlinedown.net/soft/3573.htm 2.安装 2.1 傻瓜式安装 不再赘述,略过. 2.2安装完成打开闪退 ...
- 判断字符串是否是IP地址
#include <stdio.h>#include <string.h> bool isIP(const char* str); int main(){ char str[] ...
- mysql语句实现年龄分布
select nnd as '年龄段',count(*) as '人数' from( select case when age>= and age<= then '1-10' when a ...
- Greenplum 行存、列存,堆表、AO表的原理和选择
转载自: https://github.com/digoal/blog/blob/master/201708/20170818_02.md?spm=a2c4e.11153940.blogcont179 ...
- Linux操作系统常用命令合集——第一篇-文件和目录操作(40个命令)
一.选项和参数的区别 在经过上一次的系统安装后我们已经成功登陆,登陆LInux后,我们就可以在#或$符后面去输入命令,有的时候命令后面还会跟着“选项”(英文名:options)或“参数” ...
- Ubuntu 18.04安装NVIDIA显卡驱动教程
最近遇到了在Ubuntu 18.04上安装NVIDIA显卡驱动的情况,看到一篇教程讲解的很好,拿来收藏. 安装NVIDIA显卡驱动风险极大,新手注意. 在Ubuntu 18.04上安装 ...