社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  分享创造

实例分析对比 同步I/O 与 异步I/O 请求处理

Py站长 • 11 年前 • 6973 次点击  

解释&对比

non-blocking I/O(异步I/O), 我简单的理解是“允许某一个操作可以继续进行,而不必等待某一资源的响应,预提供一个回调函数,用于处理、响应该资源的结果(当该资源返回相关内容的时候)” http://en.wikipedia.org/wiki/Asynchronous_IO

对比异步I/O,我们最常见的就是同步I/O(线性编程),一次请求访问另一个资源,必须等待该资源的成功返回,方可进行下一步操作,如果该资源无响应(或异常),程序就终止(受限)于此。

有一张图可以解释一下两者的区别:

实例分析

Tornado是一款非阻塞(异步I/O)web server,它既可以实现同步I/O请求,也可以实现异步I/O请求。

下面,我将编写几个实例来对比一下 同步请求和异步请求的不同。

实验依赖库:

  1. requests
  2. tornado

以上两个库需要预先安装。

下面开始实例:

先编写同步请求例子 synctest.py

import logging

import tornado.httpserver
import tornado.ioloop
import tornado.web
import requests


class MainHandler(tornado.web.RequestHandler):

    def get(self):
        URL = "http://localhost:8084/async-sync-test/"
        r = requests.get(URL)
        self.write(r.text + ", Hello to the Tornado world! ")


settings = {
    #"debug": True,
}

application = tornado.web.Application([
    (r"/", MainHandler),
], **settings)

if __name__ == "__main__":

    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8087)
    tornado.ioloop.IOLoop.instance().start()

再编写异步请求例子 asynctest.py

import logging

import tornado.httpserver
import tornado.ioloop
import tornado.web


from tornado.httpclient import AsyncHTTPClient

class MainHandler(tornado.web.RequestHandler):


    @tornado.web.asynchronous
    def get(self):
        http = tornado.httpclient.AsyncHTTPClient()
        http.fetch("http://localhost:8084/async-sync-test/", callback = self._test_callback)
        self.write("Hello to the Tornado world! ")
        '''
        Flushes the current output buffer to the network.
        '''
        self.flush()

    '''
    _test_callback is a callback function used for the processing of the response from the async request
    '''
    def _test_callback(self, response):
        self.write(response.body)
        '''
        refer the offical document, we are responsible for the invocation of the finish function in the async case.
        '''
        self.finish()

settings = {
    #"debug": True,
}

application = tornado.web.Application([
    (r"/", MainHandler),
], **settings)

if __name__ == "__main__":

    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8083)
    tornado.ioloop.IOLoop.instance().start()

在两个例子中,它们都请求了http://localhost:8084/async-sync-test/这个URL服务,我们为这个URL编写一个简单的WEB服务 commontest.py

import logging

import tornado.httpserver
import tornado.ioloop
import tornado.web


class MainHandler(tornado.web.RequestHandler):

    def get(self):
        '''
        The below is only a testing which will be exected to kill time,
        and then we can find the asynchronous effect from the front page.
        '''
        for i in range(1, 100000):
            print "kill time"
        self.write(


    
"hello")


settings = {
    #"debug": True,
}

application = tornado.web.Application([
    (r"/async-sync-test/", MainHandler),
], **settings)

if __name__ == "__main__":

    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(8084)
    tornado.ioloop.IOLoop.instance().start()
  • 测试实验1:

    将commontest.py服务开启(http://localhost:8084/async-sync-test/),

    然后打开同步服务 synctest.py ,访问 http://localhost:8087 ,则会显示

    hello, Hello to the Tornado world!
    

    然后打开异步服务 asynctest.py ,访问 http://localhost:8083 , 则会显示:

    Hello to the Tornado world! hello
    

    实验表示,在使用同步服务时,会处理好请求后,再返回;而在使用异步服务时,会先返回,然后再处理好请求,然后再返回。

  • 测试实验2:

    不打开commontest.py服务

    然后打开同步服务 synctest.py ,访问 http://localhost:8087 ,则会显示:

    500: Internal Server Error
    

    这说明处理时发生故障(即 无法访问 http://localhost:8084/async-sync-test/),整个请求失败了。

    然后打开异步服务 asynctest.py ,访问 http://localhost:8083 , 则会显示:

    Hello to the Tornado world!
    

    实验表示,在使用同步服务时,如果处理失败,则整个请求失败;而在使用异步服务时,如果处理失败,则请求仍然是成功的,只是处理失败的结果不会再返回了(如 “hello”没有返回了)

结论

通过合理使用同步I/O或异步I/O,可以给web应用不错的性能,以及带来不错的用户体验。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/121
 
6973 次点击  
文章 [ 1 ]  |  最新文章 11 年前
djangolover
Reply   •   1 楼
djangolover    11 年前

高端用法啊,学习学习,未来的趋势!