tornado异步
同步:
含义:指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系
现象:有一个共同的时钟,按来的顺序一个一个处理
直观感受 :就是需要等候,效率低下
异步:
含义 :双方不需要共同的时钟,也就是接收方不知道发送方什么时候发送,所以在发送的信息中就要有提示接收方开始接收的信息,如开始位,同时在结束时有停止位
现象:没有共同的时钟,不考虑顺序来了就处理
直观感受:就是不用等了,效率高
阻塞调用:
含义 : 阻塞调用是指调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,CPU不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回
现象:读套接字时没有数据等数据来,写套接字时写不下了也一直等,等能写下了往里写(套接字被写满的原因不在本地,在于网络另一头的套接字被写满了来不及读出去,导致本地的套接字内容来发不出去堵住了)
直观感受:执着
非阻塞调用:
含义 :非阻塞调用是指没有调用结果立即返回,当前线程不被挂起,可以继续做其它工作
现象:读套接字时没有数据,不等直接返回干别的事去,写套接字写不下了也不写了,直接返回干别的事去
直观感受:勤奋
手动实现异步:
import threading import time #回调函数实现异步 #2.携程实现异步 #返回数据的时候使用了不同的方式 # 在tornado里面,把这些方式封装成了装饰器 #想使用异步的时候,加上这些装饰器,就可以实现异步 # epoll 加携程实现异步 异步非阻塞框架,tornado def func(on_finish): def inner(on_finish): print('----start----') time.sleep(5) print('----end----') on_finish('hello world') #回调函数 # yield 'helloworld' #改成携程yield threading.Thread(target=inner,args=(on_finish,)).start() #改成epoll #原来使用return返回数据,但是他有瓶颈,我们使用一个函数来返回数据 def on_finish(result): print(result) func(on_finish) time.sleep(2) print('---------b---------')
函数执行结果如下:
异步编程:很多方法tornado 6.0版本已经不能使用,下面列举两种可用的
第一种:通过协程来实现异步(使用requests模块)
第一步:安装模块
pip install futures
pip install requests
第二步:导入模块
from tornado.concurrent import run_on_executor from concurrent.futures import ThreadPoolExecutor import requests
代码如下:
class ReqHandler(RequestHandler): '''通过携程来实现异步(使用requests模块)''' executor = ThreadPoolExecutor() @tornado.gen.coroutine #携程装饰器 def get(self): response = yield self.func() self.write(response.text) @run_on_executor def func(self): res = requests.get('http://127.0.0.1:8000/sync?id=2') #异步的客户端 return res
第二种:
官方推荐的方法:
class GenHandler(RequestHandler): '''当前版本官方推荐的异步案例''' @tornado.gen.coroutine #添加异步装饰器 def get(self): client = AsyncHTTPClient() #异步的客户端 response = yield client.fetch('http://127.0.0.1:8000/sync') self.write(response.body) #获取请求参数