目录
Tornado基于epoll,ioloop中运行epoll机制
更好的支持高并发,建立更多的服务器连接
底层原理
IO多路复用
IO多路复用支持三种方式:select,poll,epoll
windows\Mac:select
linux:三种都支持
select:最多只能有1024个连接
epoll:连接没有上限
poll是过渡产物
select epoll 运行机制
ioloop中有多个socket对象(绑定了IP地址和端口号)
select不断轮询所有socket对象(无论对象处于什么状态),直到有socket对象达到就绪状态
epoll只会询问所有socket对象一次,并给所有socket对象绑定监听函数,当要建立连接的时候,当某个socket对象达到就绪状态时,回调函数会通知用户,然后建立连接。
另外,当处理类中有堵塞时,直接响应状态,不返回结果,由协程继续执行其他的响应。
Tornado中的Ioloop模块的作用
ioloop就是对I/O多路复用的封装,它实现了一个单例,将这个单例保存在IOLoop._instance中
ioloop实现了Reactor模型,将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程/进程阻塞在多路复用器上;一旦有I/O事件到来或是准备就绪(文件描述符或socket可读、写),多路复用器返回并将事先注册的相应I/O事件分发到对应的处理器中。
另外,ioloop还被用来集中运行回调函数以及集中处理定时任务。
获取请求方式
get post中使用的方法
import tornado.web
import tornado.ioloop
class IndexHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
self.render('templates/login.html')
class LoginHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
# 取参数为html中的属性值
# get_arguments 取多个属性值 value属性值不同时使用
uname = self.get_argument('uname')
# get_query_xx只适用于get 请求
pwd = self.get_query_argument('pwd')
print(uname, pwd)
self.write(uname + ',' + pwd)
def post(self, *args, **kwargs):
uname = self.get_body_argument('uname')
print(uname)
self.write(uname)
app = tornado.web.Application([(r'^/$', IndexHandler),
(r'^/login/$', LoginHandler), ])
app.listen(8888)
tornado.ioloop.IOLoop.current().start()
文件上传与展示
import tornado.web
import tornado.ioloop
class UploadHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
self.render('templates/upload.html')
def post(self, *args, **kwargs):
# 获取上传的文件
# 获取的数据 [{'body':b'\0\xff\xxx',"content_type":"image/jpeg,"filename":l.jpg}]
img1 = self.request.files['img1']
# 遍历 img1
for img in img1:
body = img.get('body', '')
content_type = img.get('content_type', '')
filename = img.get('filename', '')
# 将图片存到files目录中
import os
dir = os.path.join(os.getcwd(), "files", filename)