python龙卷风框架_龙卷风python的简单异步示例

I want find simple async server example.

I have got some function with lot of wait, database transactions ... etc:

def blocking_task(n):

for i in xrange(n):

print i

sleep(1)

return i

I need run it function in separated process without blocking. Is it possible?

解决方案

Tornado is designed to run all your operations in a single thread, but utilize asynchronous I/O to avoid blocking as much as possible. If the DB you're using has asychronous Python bindings (ideally ones geared for Tornado specifically, like Motor for MongoDB or momoko for Postgres), then you'll be able to run your DB queries without blocking the server; no separate processes or threads needed.

To address the exact example you gave, where time.sleep(1) is called, you could use this approach to do it asynchronously via tornado coroutines:

#!/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()

The interesting part is async_sleep. That method is creating an asynchronous Task, which is calling the ioloop.add_timeout method. add_timeout will run a specified callback after a given number of seconds, without blocking the ioloop while waiting for the timeout to expire. It expects two arguments:

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

As you can see in the example above, we're only actually providing one parameter to add_timeout explicitly in the code, which means we end up this this:

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

We're not providing the expected callback parameter. In fact, when gen.Task executes add_timeout, it appends a callback keyword argument to the end of the explicitly provided parameters. So this:

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

Results in this being executed inside gen.Task():

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

When gen.Callback is executed after the timeout, it signals that the gen.Task is complete, and the program execution will continue on to the next line. This flow is kind of difficult to fully understand, at least at first (it certainly was for me when I first read about it). It'll probably be helpful to read over the Tornado gen module documentation a few times.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值