gpt4 book ai didi

python - tornado python 的简单异步示例

转载 作者:太空狗 更新时间:2023-10-29 20:34:47 25 4
gpt4 key购买 nike

我想找到简单的异步服务器示例。我有一些功能需要大量等待、数据库事务……等等:

def blocking_task(n):
for i in xrange(n):
print i
sleep(1)
return i

我需要在不阻塞的情况下在单独的进程中运行它的功能。可能吗?

最佳答案

Tornado 旨在在单个线程中运行所有操作,但使用异步 I/O 来尽可能避免阻塞。如果您使用的数据库具有异步 Python 绑定(bind)(最好是专为 Tornado 设计的,例如 Motor 用于 MongoDB 或 momoko 用于 Postgres),那么您将能够在不阻塞服务器的情况下运行数据库查询;不需要单独的进程或线程。

要解决您给出的确切示例,其中调用了 time.sleep(1),您可以使用这种方法通过 Tornado 协程异步执行此操作:

#!/usr/bin/python

import tornado.web
from tornado.ioloop import IOLoop
from tornado import gen
import time

@gen.coroutine
def async_sleep(seconds):
yield gen.Task(IOLoop.instance().add_timeout, time.time() + seconds)

class TestHandler(tornado.web.RequestHandler):
@gen.coroutine
def get(self):
for i in xrange(100):
print i
yield async_sleep(1)
self.write(str(i))
self.finish()


application = tornado.web.Application([
(r"/test", TestHandler),
])

application.listen(9999)
IOLoop.instance().start()

有趣的部分是async_sleep。该方法正在创建一个异步任务,它正在调用 ioloop.add_timeout 方法。 add_timeout 将在给定的秒数后运行指定的回调,而不会在等待超时到期时阻塞 ioloop。它需要两个参数:

add_timeout(deadline, callback) # deadline is the number of seconds to wait, callback is the method to call after deadline.

正如您在上面的示例中看到的,我们实际上只是在代码中显式地向 add_timeout 提供了一个参数,这意味着我们最终会这样:

add_timeout(time.time() + seconds, ???)

我们没有提供预期的回调参数。事实上,当 gen.Task 执行 add_timeout 时,它会在显式提供的参数末尾附加一个 callback 关键字参数。所以这个:

yield gen.Task(loop.add_timeout, time.time() + seconds)

结果在 gen.Task() 中执行:

loop.add_timeout(time.time() + seconds, callback=gen.Callback(some_unique_key))

当超时后执行gen.Callback时,表示gen.Task已完成,程序将继续执行到下一行。这个流程有点难以完全理解,至少一开始是这样(当我第一次读到它时对我来说肯定是这样)。阅读 Tornado gen module documentation 可能会有所帮助几次。

关于python - tornado python 的简单异步示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22920877/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com