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方式进行通信. 代码如下:(不足之处,还请高手指正) ...
随机推荐
- 【华为云】MRS journey node HDFS 不一致
HDFS JournalNode数据不同步告警 恢复指导 1 停止有问题的 JN 实例 2 清楚无效数据 登录有问题JN的后台,使用omm用户操作以下命令: cd /srv/BigData/journ ...
- PS批量制作获奖证书并导出PNG
其实方法和"使用PS批量制作视频字幕"的方法类似.区别在于制作视频字幕时导出成psd格式就可以直接导入Premiere中使用了,而获奖证书考虑到打印设备有无PS的不确定性,可能需要 ...
- Centos 6.x开机启动流程
Centos 6.x开机启动流程 BIOS(COMS)检查 加载Bios,bios包含所有硬件信息(CPU,内存,硬盘,时钟,鼠标键盘等等) 读MBR 硬盘上第0磁道第一个扇区被称为MBR(maste ...
- 用js刷剑指offer(从上到下打印二叉树)
题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 牛客网链接 js代码 /* function TreeNode(x) { this.val = x; this.left = null ...
- <<构建之法>>--第二次作业
GIT地址 https://github.com/Panghu98/AchaoCalculator.git GIT用户名 Panghu98 学号后五位 62632 博客地址 https://www.c ...
- rabbitmq二进制安装
一.erland的安装 1.首先测试一下是否已经安装了erlang,命令 rpm -qa | grep erlang 2.没有安装则用yum安装 yum install erlang -y 二.下载r ...
- 关于Go Modules的一些内容
安装 配置环境 启用Go Modules go mod在Go >= 1.13才默认启用,在Go >= 1.11已经开始支持了go mod. 设置环境变量 # 启用go module exp ...
- logstash可以考虑在项目中用起来
在用Node.js开发项目的时候,我们常用 log4js 模块来进行日志的记录,可以通过配置 log4js 的 Appenders 将日志输出到Console.File和GELF等不同的地方. log ...
- vue-cli3项目搭建配置以及性能优化
项目初始化 注意:安装前请确保有安装node.js,并且node>=8.9 全局安装vue npm install -g @vue/cli 如果之前安装了vue旧版本,查看vue --versi ...
- 更新studio 3T的试用期时间
j@echo off ECHO 重置Studio 3T的使用日期...... FOR /f "tokens=1,2,* " %%i IN ('reg query "HKE ...