Tornado使用-队列Queue
1.tornado队列的特点
和python标准队列queue相比,tornado的队列Queue支持异步
2.Queue常用方法
Queue.get()
会暂停,直到queue中有元素
Queue.put()
对有最大长度限制的队列,会暂停,直到队列有空闲空间
Queue.task_done()
对每一个get元素,紧接着调用task_done(),表示这个任务执行完毕
Queue.join()
等待,直到所有任务都执行完毕,即所有元素都调用了task_done()
3.示例
给出一个地址http://www.tornadoweb.org/en/stable/,分析页面中所有以这个url为前缀的链接,
并依次访问,解析,直到找出所有的url
#!/usr/bin/env python
import time
from datetime import timedelta
try:
from HTMLParser import HTMLParser
from urlparse import urljoin, urldefrag
except ImportError:
from html.parser import HTMLParser
from urllib.parse import urljoin, urldefrag
from tornado import httpclient, gen, ioloop, queues
base_url = 'http://www.tornadoweb.org/en/stable/'
concurrency = 10
@gen.coroutine
def get_links_from_url(url):
"""Download the page at `url` and parse it for links.
Returned links have had the fragment after `#` removed, and have been made
absolute so, e.g. the URL 'gen.html#tornado.gen.coroutine' becomes
'http://www.tornadoweb.org/en/stable/gen.html'.
"""
try:
response = yield httpclient.AsyncHTTPClient().fetch(url)
print('fetched %s' % url)
html = response.body if isinstance(response.body, str) \
else response.body.decode()
urls = [urljoin(url, remove_fragment(new_url))
for new_url in get_links(html)]
except Exception as e:
print('Exception: %s %s' % (e, url))
raise gen.Return([])
raise gen.Return(urls)
def remove_fragment(url):
pure_url, frag = urldefrag(url)
return pure_url
def get_links(html):
class URLSeeker(HTMLParser):
def __init__(self):
HTMLParser.__init__(self)
self.urls = []
def handle_starttag(self, tag, attrs):
href = dict(attrs).get('href')
if href and tag == 'a':
self.urls.append(href)
url_seeker = URLSeeker()
url_seeker.feed(html)
return url_seeker.urls
@gen.coroutine
def main():
q = queues.Queue()
start = time.time()
fetching, fetched = set(), set()
@gen.coroutine
def fetch_url():
current_url = yield q.get()
try:
if current_url in fetching:
return
print('fetching %s' % current_url)
fetching.add(current_url)
urls = yield get_links_from_url(current_url)
fetched.add(current_url)
for new_url in urls:
# Only follow links beneath the base URL
if new_url.startswith(base_url):
yield q.put(new_url)
finally:
q.task_done()
@gen.coroutine
def worker():
while True:
yield fetch_url()
q.put(base_url)
# Start workers, then wait for the work queue to be empty.
for _ in range(concurrency):
worker()
yield q.join(timeout=timedelta(seconds=300))
assert fetching == fetched
print('Done in %d seconds, fetched %s URLs.' % (
time.time() - start, len(fetched)))
if __name__ == '__main__':
import logging
logging.basicConfig()
io_loop = ioloop.IOLoop.current()
io_loop.run_sync(main)
运行结果:
fetching http://www.tornadoweb.org/en/stable/
fetched http://www.tornadoweb.org/en/stable/
......
fetched http://www.tornadoweb.org/en/stable/_modules/index.html
fetched http://www.tornadoweb.org/en/stable/_modules/tornado/util.html
Done in 11 seconds, fetched 122 URLs.
使用yield,当队列有元素时,q.get()会执行
for _ in range(concurrency): worker()
可以大幅提高效率,原因在于get_links_from_url网络IO会占用较多执行时间,多个异步任务可以并行访问网络io,大大提高了效率。
q.join()会阻塞主程序,直到队列所有的任务都执行完毕
Tornado使用-队列Queue的更多相关文章
- Python进阶【第二篇】多线程、消息队列queue
1.Python多线程.多进程 目的提高并发 1.一个应用程序,可以有多进程和多线程 2.默认:单进程,单线程 3.单进程,多线程 IO操作,不占用CPU python的多线程:IO操作,多线程提供并 ...
- Java中的队列Queue,优先级队列PriorityQueue
队列Queue 在java5中新增加了java.util.Queue接口,用以支持队列的常见操作.该接口扩展了java.util.Collection接口. Queue使用时要尽量避免Collecti ...
- jquery 的队列queue
使用示列代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...
- Windows Azure Service Bus (2) 队列(Queue)入门
<Windows Azure Platform 系列文章目录> Service Bus 队列(Queue) Service Bus的Queue非常适合分布式应用.当使用Service Bu ...
- Windows Azure Service Bus (3) 队列(Queue) 使用VS2013开发Service Bus Queue
<Windows Azure Platform 系列文章目录> 在之前的Azure Service Bus中,我们已经介绍了Service Bus 队列(Queue)的基本概念. 在本章中 ...
- (C#)使用队列(Queue)解决简单的并发问题
(C#)使用队列(Queue)解决简单的并发问题 2015-07-16 13:04 13265人阅读 评论(8) 收藏 举报 分类: Asp.Net(8) 版权声明:本文为博主原创文章,未经博主允 ...
- STL中的单向队列queue
转载自:http://blog.csdn.net/morewindows/article/details/6950917 stl中的queue指单向队列,使用时,包含头文件<queue>. ...
- java09 队列Queue与Deque
队列Queue与Deque. Enumeration Hashtable与Hashtable子类Properties(资源配置文件) 引用类型(强.软.弱.虚)与WeakHashMap Identit ...
- 队列Queue和栈
1.队列Queue是常用的数据结构,可以将队列看成特殊的线性表,队列限制了对线性表的访问方式,只能从线性表的一段添加(offer)元素, 从另一段取出(poll)元素,队列遵循先进先出的原则. 2.J ...
随机推荐
- Electromagnetic radiation and Radio 电磁波/电磁辐射和无线电波
电磁辐射,又称电磁波,是由同相振荡且互相垂直的电场与磁场在空间中以波的形式传递能量和动量,其传播方向垂直于电场与磁场构成的平面. 电磁辐射的载体为光子,不需要依靠介质传播,在真空中的传播速度为光速.电 ...
- 【onethink搬家】win环境移植linux环境,注意事项
onethink 搬家注意事项: 修改目录/文件归属和权限,Runtime目录要有可写权限. 若数据库有变动,则需要更改数据库连接参数.在Application/Common/Conf/config. ...
- 你想知道的关于JavaScript作用域的一切(译)
原文链接: Everything you wanted to know about JavaScript scope 原文作者: Todd Motto JavaScript中有许多章节是关于scope ...
- Git: fatal: Pathspec is in submodule
出现是问题: git提交代码是出现fatal: Path 'directory/file' is in submodule 'directory''错误 Removing the directory ...
- ios中layoutsubview何时被调用
layoutsubview和viewDidlayoutsubview(控制器)被调用的集中情况 一:当view的frame或bounds发生改变 1:直接改view的frame或bounds 会调用v ...
- open()系统调用的实现
open系统调用的服务例程是sys_open()函数,它接受三个参数:要打开文件的路径名filename, 访问模式的表示flags和文件权限掩码mode.在内核中,sys_open实际调用do_sy ...
- JavaScript Window History 浏览器的历史
window.history 对象在编写时可不使用 window 这个前缀. 为了保护用户隐私,对 JavaScript 访问该对象的方法做出了限制. 一些方法: history.back() - 与 ...
- 关于Linux防火墙'iptables'的面试问答
1. 你听说过Linux下面的iptables和Firewalld么?知不知道它们是什么,是用来干什么的? 答案 : iptables和Firewalld我都知道,并且我已经使用iptables好一段 ...
- JAVA操作mysql
所需jar包:mysql-connector-java.jar 代码: import java.sql.*; import java.util.ArrayList; import java.util. ...
- Oracle2MySQL注意事项
在Oracle切换成MySQL时,会碰到如下注意事项: Oracle中的sysdate在MySQL中是不支持的: Oracle中的分布方案在MySQL中的实现: Oracle中的SQL语句是大小写不敏 ...