基本IO模型
网上搜了很多关于同步异步,阻塞非阻塞的说法,理解还是不能很透彻,有必要买书看下。
参考:使用异步 I/O 大大提高应用程序的性能
怎样理解阻塞非阻塞与同步异步的区别?
同步和异步:主要关注消息通信机制(重点在B?)。
同步:A调用B,B处理直到获得结果,才返回给A。
异步:A调用B,B直接返回。无需等待结果,B通过状态,通知等来通知A或回调函数来处理。阻塞和非阻塞:主要关注程序等待(重点在A?)。
阻塞:A调用B,A被挂起直到B返回结果给A,A继续执行。
非阻塞:A调用B,A不会被挂起,A可以执行其他操作(但可能A需要轮询检查B是否返回)。同步阻塞:A调用B,A挂起,B处理直到获得结果,返回给A,A继续执行。
- 同步非阻塞:A调用B,A继续执行,B处理直到获得结果,处理的同时A轮询检查B是否返回结果。
- 异步阻塞:异步阻塞 I/O 模型的典型流程 (select)。
- 异步非阻塞:A调用B,B立即返回,A继续执行,B得到结果后通过状态,通知等通知A或回调函数处理。
tornado实现异步非阻塞
参考:
1. 使用tornado让你的请求异步非阻塞
2. 官方文档
利用异步方法(回调)和@tornado.web.asynchronous
@tornado.web.asynchronous
并不能将一个同步方法变成异步,所以修饰在同步方法上是无效的,只是告诉框架,这个方法是异步的,且只能适用于HTTP verb方法(get、post、delete、put等)。@tornado.web.asynchronous
装饰器适用于callback-style的异步方法,如果是协程则可以用@tornado.gen.coroutine
来修饰。对于用@tornado.web.asynchronous
修饰的异步方法,需要主动self.finish()
来结束该请求,普通的方法(get()
等)会自动结束请求在方法返回的时候。
最基本的使用callback-style的例子,直接使用异步方法,并定义callback方法。
# sync blocking
class SleepHandler(BaseHandler):
# no effective
@tornado.web.asynchronous
def get(self):
time.sleep(5)
self.write('sleep for 5s')
class SleepHandler(BaseHandler):
@tornado.web.asynchronous
def get(self):
tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 5, callback=self.on_response)
def on_response(self):
self.write('sleep for 5s')
self.finish()
# call back
class MyRequestHandler(BaseHandler):
@tornado.web.asynchronous