zoukankan      html  css  js  c++  java
  • tornado 异步非阻塞

    1、同步阻塞

       A、socket例子

    import socket
    def handle_request(client):
    buf = client.recv(1024)
    client.send(b"HTTP/1.1 200 OK ")
    client.send(b"Hello, Seven")

    def main():
    print('main()')
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('localhost', 8083))
    sock.listen(5)
    while True:
    connection, address = sock.accept()
    handle_request(connection)
    connection.close()

    if __name__ == '__main__':
    main()

    例子A为socket监听浏览器行为的过程并且返回浏览器访问数据

    B、tornado同步阻塞例子
    import tornado.ioloop
    import tornado.web
    import requests
    class MainHandler(tornado.web.RequestHandler):
    def get(self):
    requests.get('http://www.google.com/')

    class LoginHandler(tornado.web.RequestHandler):
    def get(self):
    self.write("Hello, world")

    application = tornado.web.Application([
    (r"/index", MainHandler),
    (r"/login", LoginHandler),
    ])

    if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
    例子B为tornado同步阻塞的例子:如果访问index页面,http://www.google.com/如果被阻塞,此时访问/login,服务器也无法处理/login的请求行为,/login因为/index阻塞而被阻塞;

    上述原因:

      1、浏览器其实就是一个socket客户端,而web应用其实就是一个socket服务端,并且web应用在服务器上一直在监听某个端口。

      2、当浏览器请求某个web应用时,需要指定服务器的IP(DNS解析)和端口建立一个socket连接。

      3、建立链接后,web应用根据请求的不同,给用户返回相应的数据。

      4、断开socket连接。(之所以说http是短链接,其实就是因为每次请求完成后,服务器就会断开socket链接)

      对于Web框架来说,一般分为两类,其中一类则是包含上述 4部分 内容的框架,另外一类就是只包含 第3部分 功能的框架。tornado就是一中属于前者的框架。tornado 是一个基于 Python 开发的web框架,较其他 Web 框架的区别是:采用了非阻塞的方式和对epoll的应用。这意味着对于实时 Web 服务来说,Tornado 是一个理想的 Web 框架。

     

    2、解决同步阻塞

    A、装饰器 + Future 从而实现Tornado的异步非阻塞

    import tornado.ioloop
    import tornado.web
    from tornado.web import asynchronous
    from tornado import gen #tornado中的协程模块:tornado.gen:
    from concurrent.futures import Future
    import time
    class AsyncHandler(tornado.web.RequestHandler):
    '''
    Future实现非阻塞
    '''
    @gen.coroutine
    def get(self):
    future = Future()
    tornado.ioloop.IOLoop.current().add_timeout(time.time() + 10, self.doing)
    future.add_done_callback(self.doing)
    yield future
    # 或
    # tornado.ioloop.IOLoop.current().add_future(future,self.doing)
    # yield future

    def doing(self, *args, **kwargs):
    self.write('async')
    self.finish()

    class LoginHandler(tornado.web.RequestHandler):
    def get(self):
    self.write("Hello, world")

    application = tornado.web.Application([
    (r"/index", AsyncHandler),
    (r"/login", LoginHandler),
    ])

    if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
    如果访问index页面,AsyncHandler中需要等待,被阻塞,此时访问/login,服务器也可以处理/login的请求行为,/login不会因为/index阻塞而被阻塞;

    B、Tornado提供了httpclient类库用于发送Http请求,装饰器 + httpclient配合Tornado的异步非阻塞使用。

    import tornado.ioloop
    import tornado.web
    from tornado import httpclient
    from tornado.web import asynchronous
    from tornado import gen #tornado中的协程模块:tornado.gen:

    class MainHandler(tornado.web.RequestHandler):
    '''
    httpclient 方式实现非阻塞
    '''
    @asynchronous
    @gen.coroutine
    def get(self):
    print
    'start get '
    http = httpclient.AsyncHTTPClient()
    http.fetch("http://www.google.com/", self.callback)
    self.write('end')

    def callback(self, response):
    print(response.body)

    class LoginHandler(tornado.web.RequestHandler):
    def get(self):
    self.write("Hello, world")

    application = tornado.web.Application([
    (r"/index", MainHandler),
    (r"/login", LoginHandler),
    ])

    if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()
    如果访问index页面,AsyncHandler中需要等待,被阻塞,此时访问/login,服务器也可以处理/login的请求行为,/login不会因为/index阻塞而被阻塞;
  • 相关阅读:
    stm32入门
    Shell入门
    广播与组播
    超时接收
    socket的四种IO模型
    网络套接字socket
    网络基础
    慢速系统调用被中断
    C# 程序运行时间计算
    HTTP的传输编码(Transfer-Encoding:chunked) / net::ERR_INVALID_CHUNKED_ENCODING
  • 原文地址:https://www.cnblogs.com/yoyo008/p/9305975.html
Copyright © 2011-2022 走看看