转自:http://www.tornadoweb.org/en/stable/faq.html

Frequently Asked Questions

Why isn’t this example with time.sleep() running in parallel?

Many people’s first foray into Tornado’s concurrency looks something like this:

class BadExampleHandler(RequestHandler):
def get(self):
for i in range(5):
print(i)
time.sleep(1)

Fetch this handler twice at the same time and you’ll see that the second five-second countdown doesn’t start until the first one has completely finished. The reason for this is that time.sleep is ablocking function: it doesn’t allow control to return to the IOLoop so that other handlers can be run.

Of course, time.sleep is really just a placeholder in these examples, the point is to show what happens when something in a handler gets slow. No matter what the real code is doing, to achieve concurrency blocking code must be replaced with non-blocking equivalents. This means one of three things:

  1. Find a coroutine-friendly equivalent. For time.sleep, use tornado.gen.sleep instead:

    class CoroutineSleepHandler(RequestHandler):
    @gen.coroutine
    def get(self):
    for i in range(5):
    print(i)
    yield gen.sleep(1)

    When this option is available, it is usually the best approach. See the Tornado wiki for links to asynchronous libraries that may be useful.

  2. Find a callback-based equivalent. Similar to the first option, callback-based libraries are available for many tasks, although they are slightly more complicated to use than a library designed for coroutines. These are typically used with tornado.gen.Task as an adapter:

    class CoroutineTimeoutHandler(RequestHandler):
    @gen.coroutine
    def get(self):
    io_loop = IOLoop.current()
    for i in range(5):
    print(i)
    yield gen.Task(io_loop.add_timeout, io_loop.time() + 1)

    Again, the Tornado wiki can be useful to find suitable libraries.

  3. Run the blocking code on another thread. When asynchronous libraries are not available,concurrent.futures.ThreadPoolExecutor can be used to run any blocking code on another thread. This is a universal solution that can be used for any blocking function whether an asynchronous counterpart exists or not:

     # `pip install futures` for python2
    executor = concurrent.futures.ThreadPoolExecutor(8)
    
    class ThreadPoolHandler(RequestHandler):
    @gen.coroutine
    def get(self):
    for i in range(5):
    print(i)
    yield executor.submit(time.sleep, 1)

See the Asynchronous I/O chapter of the Tornado user’s guide for more on blocking and asynchronous functions.

My code is asynchronous, but it’s not running in parallel in two browser tabs.

Even when a handler is asynchronous and non-blocking, it can be surprisingly tricky to verify this. Browsers will recognize that you are trying to load the same page in two different tabs and delay the second request until the first has finished. To work around this and see that the server is in fact working in parallel, do one of two things:

  • Add something to your urls to make them unique. Instead of http://localhost:8888 in both tabs, load http://localhost:8888/?x=1 in one and http://localhost:8888/?x=2 in the other.
  • Use two different browsers. For example, Firefox will be able to load a url even while that same url is being loaded in a Chrome tab.

Frequently Asked Questions的更多相关文章

  1. tmux frequently asked questions

    tmux frequently asked questions How is tmux different from GNU screen?     tmux and GNU screen have ...

  2. Relinking Oracle Home FAQ ( Frequently Asked Questions) (Doc ID 1467060.1)

    In this Document   Purpose   Questions and Answers   1)  What is relinking ?   2)  What is relinking ...

  3. 06 Frequently Asked Questions (FAQ) 常见问题解答 (常见问题)

    Frequently Asked Questions (FAQ) Origins 起源 What is the purpose of the project? What is the history ...

  4. 成员函数指针 C++ FAQ LITE — Frequently Asked Questions

    http://www.sunistudio.com/cppfaq/pointers-to-members.html C++ FAQ LITE — Frequently Asked Questions ...

  5. openvswith Frequently Asked Questions

    Open vSwitch <http://openvswitch.org> 参考地址:http://git.openvswitch.org/cgi-bin/gitweb.cgi?p=ope ...

  6. Kafka Frequently Asked Questions

    This is intended to be an easy to understand FAQ on the topic of Kafka. One part is for beginners, o ...

  7. NFC Forum : Frequently Asked Questions (NFC 论坛:FAQ)

    NFC for Business What is the NFC Forum? The NFC Forum is a not-for-profit industry organization whos ...

  8. 工作笔记20170315-------关于FAQ(Frequently Asked Questions)列表的代码

    源自于:http://www.17sucai.com/pins/3288.html (1)FAQ问答列表点击展开收缩文字列表 <ul>   <li class="clear ...

  9. Frequently Asked Questions - P-thresholds

    Source: http://mindhive.mit.edu/book/export/html 1. What is the multiple-comparison problem? What is ...

随机推荐

  1. Python 字典的增删改查

    dic = {"意大利": "李云龙","美国":"美国往事"} dic["日本"] = " ...

  2. asp.net mvc 快捷下拉列表

    各种表单中可能经常会遇到使用各种下拉列表的地方, 有些数据是从数据库来的, 有些则是固定数值, 为了方便, 快速的构造一个可以保持状态的下拉列表, 就出现了下面的方法 2分钟构思的代码, 比较粗糙, ...

  3. 服务器购买+建站流程教程——适合新手没有经验的人Chinar总结

    服务器购买购买教程 本文提供全图文流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享.心创 ...

  4. ReSharper2017.3的列对齐、排版格式、列对齐错误的修复

    ReSharper代码排版格式 列对齐 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- ...

  5. Codeforces 208A:Dubstep(字符串)

    题目链接:http://codeforces.com/problemset/problem/208/A 题意 给出一个字符串,将字符串中的WUB给删去,如果两个字母间有WUB,则这两个字母用空格隔开 ...

  6. (转)typedef和define的详细区别

    来源:http://developer.51cto.com/art/201104/256060.htm typedef是一种在计算机编程语言中用来声明自定义数据类型,配合各种原有数据类型来达到简化编程 ...

  7. GIT与VCS

    GIT 是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理. [Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制 ...

  8. tiny4412-Uboot启动分析

    一.从本质上将,引导转载程序至少应提供以下功能 (1)设置和初始化RAM (2)初始化一个串口 (3)检测机器类型(machine type) (4)设置内核标签列表(tag list) (5)调用内 ...

  9. MySQL账号安全设置

    ======================================================================== 推荐账号安全设置 在数据库服务器上严格控制操作系统的账 ...

  10. 使用Apriori进行关联分析(一)

    大型超市有海量交易数据,我们可以通过聚类算法寻找购买相似物品的人群,从而为特定人群提供更具个性化的服务.但是对于超市来讲,更有价值的是如何找出商品的隐藏关联,从而打包促销,以增加营业收入.其中最经典的 ...