tornado属于单线程单进程,阻塞、非阻塞只针对线程层面来说,简单理解为:
阻塞:tornado实例不能在接受其他API的请求
非阻塞:tornado实例可以接受其他API的请求
同步、异步,属于业务逻辑上的东西。假设:
你的业务逻辑API需要1,2,3步才能完成,按照同步的方法:
同步执行时,这个API只有完成第三步后,才能再次接受其他的请求。
异步执行时,比如把2,3步合并为4,把4交给内核调度,tornado的IOLoop循环来异步执行,yield func4(callback)注册一个回调函数,有结果通知/处理(见例1)。后面的代码会继续执行。那么这个API就是异步了,API在处理1之后,线程就属于空闲状态了,所以线程现在处于非阻塞,可以接受其他的请求。
但是如果你要等待4的结果返回后,也就是result=yield func4(callback),这时候,API后面的流程就变同步了,都在等待result(见例2)。但线程不会被阻塞。可以接受其他请求。
上面提到的func4必须是异步的写法,也就是需要用到IOLoop的东西,而不是随便一个函数都可以,因为它需要交给IOLoop来循环执行。这样才是异步函数。
例子1:
异步回调,非阻塞:线程不被阻塞,API逻辑是异步执行的
class asyn_callback(BaseHandler):
@tornado.gen.coroutine
def get(self, *args, **kwargs):
print 1
client = AsyncHTTPClient()
client.fetch("http://www.hao123.com")
print 2
def func(self, response):
print response
例子2:
异步等待,非阻塞:线程不被阻塞,但API业务逻辑同步执行的,因为它要等结果
class asyn_callback(BaseHandler):
@tornado.gen.coroutine
def get(self, *args, **kwargs):
print 1
client = AsyncHTTPClient()
result = yield client.fetch("http://www.hao123.com")
print result
print 2