Py学习  »  分享创造

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

Py站长 • 12 年前 • 7306 次点击  

解释&对比

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
 
7306 次点击  
文章 [ 1 ]  |  最新文章 12 年前
djangolover
Reply   •   1 楼
djangolover    12 年前

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