关于Python Tornado&block阻止的困惑

时间:2015-10-15 18:40:14

标签: python tornado nonblocking

所以我理解Tornado本身是非阻塞事件循环I / O的基本思想,但阻止IO操作(如数据库访问)会导致Tornado在这些操作期间阻塞。

我不明白为什么看起来Tornado在非阻塞操作期间会阻塞。

我在处理程序中有以下代码:

class MyHandler(BaseHandler):

    def get(self):
        x = 0
        for i in xrange(0,500000000):
            x = i

        self.render("page_temp.html",
                    title="Page"
                    )

加载页面大约需要20秒。如果我打开另一个浏览器窗口并尝试加载任何其他页面,我会挂起,直到20秒页面加载。可能是因为这两个请求来自同一个用户吗?

1 个答案:

答案 0 :(得分:4)

您正在处理程序中直接进行长时间的CPU操作。 tornado是单线程的,这意味着它不能在事件循环线程中执行CPU绑定工作,而不会阻止所有其他请求。如果您需要执行CPU绑定工作,则必须在后台线程或进程中执行此操作。

为了使此方法同时处理请求,它需要如下所示:

from concurrent.futures import ThreadPoolExecutor
from tornado import gen
from tornado.web import RequestHandler

executor = ThreadPoolExecutor(8) # 8 Threads in the pool

class ThreadPoolHandler(RequestHandler):

    def _do_loop(self):
        x = 0
        for i in xrange(0,500000000):
            x = i

    @gen.coroutine
    def get(self):
        yield executor.submit(self._do_loop) # Run through the loop without blocking tornado
        self.render("page_temp.html",
                    title="Page"
                    )

通过使用ThreadPoolExecutor在后​​台线程中运行昂贵的for循环,tornado可以在等待CPU工作完成时继续提供其他请求。