为什么龙卷风不同时出现?

时间:2015-02-07 21:15:31

标签: python asynchronous tornado

以下是我的测试代码。我正在使用Python2.7,安装futures使用:

pip install futures

以下是我的演示代码:

import tornado.ioloop
import tornado.web
from tornado.gen import coroutine, Task
from tornado.concurrent import Future
import time


class MainHandler(tornado.web.RequestHandler):
    @coroutine
    def get(self):
        print "in"
        res = yield Task(self._work)
        self.write(res)

    def _work(self, callback):
        time.sleep(10)
        callback("hello world!")

if __name__ == "__main__":
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

这段代码应该同时进行,不应该吗?但是,它没有。

我用Firefox和IE测试过。我想我犯了一些错误。你指出我的错误会很好。

一次只能有一个请求(http://localhost:8888/

import tornado.ioloop
import tornado.web
from tornado.gen import coroutine, Return, Task
from tornado.process import Subprocess
from tornado.concurrent import Future
from threading import Thread
import time

@coroutine
def async_sleep(timeout):
    """ Sleep without blocking the IOLoop. """
    yield Task(tornado.ioloop.IOLoop.instance().add_timeout, time.time() + timeout)

class MainHandler(tornado.web.RequestHandler):
    @coroutine
    def get(self):
        print "in"
        res = yield self._work()
        self.write(res)

    @coroutine
    def _work(self):
        yield async_sleep(5)
        raise Return("hello world!")

if __name__ == "__main__":
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    application.listen(8888)
    ioloop=tornado.ioloop.IOLoop.instance()
    Thread(target=ioloop.start).start()

2 个答案:

答案 0 :(得分:7)

由于您在评论中指出要通过龙卷风运行子流程,下面是一个说明如何执行此操作的示例。我还修改了一个逻辑错误,当你在调用Task时创建一个_work时,这不会按照你想要的方式工作:

import tornado.ioloop
import tornado.web
from tornado.gen import coroutine, Return
from tornado.process import Subprocess
from tornado.concurrent import Future

class MainHandler(tornado.web.RequestHandler):
    @coroutine
    def get(self):
        print "in"
        res = yield self._work()
        self.write(res)

    @coroutine
    def _work(self):
        p = Subprocess(['sleep', '10'])
        f = Future()
        p.set_exit_callback(f.set_result)
        yield f
        raise Return("hello world!")

if __name__ == "__main__":
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

如您所见,我将_work作为协程,然后使用tornado's built-in Subprocess类来执行命令。我创建了一个Future对象,并指示Subprocess在完成后调用Future.set_result(return_code_of_subprocess)。然后我在yield实例上调用了Future。这使代码等到子进程完成,而不会阻塞I / O循环。

答案 1 :(得分:0)

代码中的time.sleep是阻止方法 你需要tornado.gen.sleep(一种非阻塞方法,龙卷风4.1中的新方法)。