1.单线程
tornado.web:基础web框架模块
tornado.ioloop:核心IO循环模块,高效的基础。封装了:
1.asyncio 协程,异步处理
2. epoll模型:水平触发(状态改变就询问,select(),poll()), 边缘触发(一直询问,epoll())
3.poll 模型:I/O多路复用技术
4.BSD(UNIX操作系统中的一个分支的总称)的kqueue(kueue是在UNIX上比较高效的IO复用技术)
epoll和kqueue的区别如下:
‘epoll‘仅适用于文件描述符,在Unix中,一切都是文件”。
这大多是正确的,但并非总是如此。例如,计时器不是文件。
信号不是文件。信号量不是文件。进程不是文件。
(在Linux中)网络设备不是文件。类UNIX操作系统中有许多不是文件的东西
。您不能使用select()/ poll()/ epoll来复制那些“事物”。
Linux支持许多补充系统调用,signalfd(),eventfd()和timerfd_create()
它们将非文件资源转换为文件描述符,以便您可以将它们与epoll()复用。
epoll甚至不支持所有类型的文件描述符;
select()/ poll()/ epoll不适用于常规(磁盘)文件。
因为epoll 对准备模型有很强的假设; 监视套接字的准备情况,
以便套接字上的后续IO调用不会阻塞。但是,磁盘文件不适合此模型,因为它们总是准备就绪。
kqueue 中,通用的(struct kevent)系统结构支持各种非文件事件
import tornado.web#tornado.web:基础web框架模块
import tornado.ioloop#tornado.ioloop:核心IO循环模块,高效的基础。
class IndexHandler(tornado.web.RequestHandler):
#类比Django中的视图,相当于业务逻辑处理的类
def get(self): #处理get请求的,并不能处理post请求
self.write("good boy") #响应http的请求
if __name__=="__main__":
"""
实例化一个app对象
Application:他是tornado.web框架的核心应用类,是与服务器对应的一个接口
里面保存了路由映射表,还有一个listen方法,可以认为用来创建一个http的实例
并绑定了端口
"""
app = tornado.web.Application([
(r"/" ,IndexHandler),
])
app.listen(8888) #绑定监听端口,但此时的服务器并没有开启监听
tornado.ioloop.IOLoop.current().start()
#Application([(r"/" ,IndexHandler),])传入的第一个参数是
#路由路由映射列表,但是在此同时Application还能定义更多参数
#IOLoop.current():返回当前线程的IOLoop实例
#例如实例化对象 ss=run() ,ss.start()
#start():启动了IOloop实例的循环,连接客服端后,同时开启了监听
原理如下:
linux-epoll进行管理多个客服端socket
tornado-IoLoop不断进行询问epoll:小老弟,有没有我需要做的事吗?
当epoll返回说:老哥,有活了
tornado-IoLoop将活上传给tornado.web.Application
tornado.web.Application中有 路由映射表
就会将socket进行一个路由匹配
把socket匹配给相对应的Handler(处理者)
Handler(处理者)处理后将数据返回给对应的socket,
(这里因为可能会延时响应,所以这里进行异步处理)
socket然后再传给了客服端浏览器。