Tornado---异步非阻塞(1)

本文深入探讨了同步和异步的概念,对比了两者在处理时间变化的量时的不同特性,详细解析了同步与异步在网络请求、进程处理中的具体应用,并通过tornado框架的实例演示了如何在实际开发中实现异步处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

同步:指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系 现象:有一个共同的时钟,按来的顺序一个一个处理。

异步:双方不需要共同的时钟,也就是接收方不知道发送方什么时候发送,所以在发送的信息中就要有提示接收方开始接收的信息,如开始位,同时在结束时有停止位 现象:没有共同的时钟,不考虑顺序来了就处理。 

同步:执行一个操作之后,等待结果,然后才继续执行后续的操作。

异步:执行一个操作后,可以去执行其他的操作,然后等待通知再回来执行刚才没执行完的操作。

阻塞:进程给CPU传达一个任务之后,一直等待CPU处理完成,然后才执行后面的操作。

非阻塞:进程给CPU传达任务后,继续处理后续的操作,隔断时间再来询问之前的操作是否完成。这样的过程其实也叫轮询。

# -*- coding:utf-8 -*-
import tornado.ioloop
import tornado.web

# from data.table_1 import User
from tornado.web import authenticated

# from pycket.session import SessionMixin

import tornado.websocket
from datetime import datetime
import time

import tornado.options
import tornado.httpserver
from tornado.options import define, options


define('port',default=8008, help='run port', type=int)
define('version', default=0.1, help='version', type=str)


class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        pass
        # current_user = self.get_secure_cookie('ID')
        # current_user = self.session.get('ID')
        # if current_user:
        #     return current_user
        # return None


class AbcHandler(BaseHandler):
    def get(self):
        print "AbcHandler被调用了======>>>"
        self.write('nnn')


import tornado.httpclient
class SyncHandler(BaseHandler):
    def get(self):
        # 同步HTTPClient
        client = tornado.httpclient.HTTPClient()
        # 8000已经启动,去访问sync(相当于调用接口)
        response = client.fetch('http://127.0.0.1:8003/sync')  
        print "同步http请求得到响应===>", response.body
        self.write('----SyncHandler---')


# 可能发生阻塞用异步
class CallbackHandler(BaseHandler):
    """  1.通过回调函数实现异步 """
    @tornado.web.asynchronous  # 将请求变成长连接
    def get(self):
        # 异步AsyncHTTPClient
        client = tornado.httpclient.AsyncHTTPClient()
        # 阻塞完毕后调用 callback
        response = client.fetch('http://127.0.0.1:8003/sync', callback=self.on_response)
        print "异步http请求得到响应===>", response
        self.write('OK'+'<br>')

    def on_response(self, response):
        print "on_response被调用了======>>>", response
        self.write('----CallbackSyncHandler---')
        self.finish()   # 回调结束,请求结束,响应到浏览器(否则浏览器一直等待状态)


import tornado.gen
class GenHandler(BaseHandler):
    """ 2.通过协程实现异步 yield """
    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def get(self):
        client = tornado.httpclient.AsyncHTTPClient()     # 异步
        # 节省内存(暂停)
        response = yield tornado.gen.Task(client.fetch, 'http://127.0.0.1:8003/sync')
        print "异步http请求得到响应===>", response
        self.write('---gen----')


class FuncHandler(BaseHandler):
    """ 3.通过协程实现异步  yield 调用函数 @tornado.gen.coroutine装饰函数(函数需要用到yield)"""
    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def get(self):
        response = yield self.fun()
        print "response======>", response
        self.write('---gen----')

    @tornado.gen.coroutine
    def fun(self):
        print "fun()函数被调用了======>"
        client = tornado.httpclient.AsyncHTTPClient()     # 异步
        response = yield tornado.gen.Task(client.fetch, 'http://127.0.0.1:8003/sync')
        raise tornado.gen.Return(response)


from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPoolExecutor # (它是由thread模块封装的(创建线程的模块))
import requests
class ExeHandler(BaseHandler):
    """ 4.通过协程实现异步  yield 调用函数 @run_on_executor装饰函数(函数不用yield)
    需要下载requests 和futures"""
    executor = ThreadPoolExecutor() # 当发生阻塞时,能够创建一个新的线程来执行阻塞的任务(多线程)
    @tornado.web.asynchronous
    @tornado.gen.coroutine
    def get(self):
        response = yield self.fun()
        print "response======>", response
        self.write('---exe----')
        self.finish()

    @run_on_executor
    def fun(self):
        print "fun()函数被调用了======>"
        response = requests.get('http://127.0.0.1:8003/sync')
        return response

application = tornado.web.Application(
    handlers=[
        (r"/sync", SyncHandler),
        (r"/abc", AbcHandler),
        (r"/callback", CallbackHandler),
        (r"/gen", GenHandler),
        (r"/func", FuncHandler),
        (r"/exe", ExeHandler),
    ],
    cookie_secret='haha',
    debug=True
)


if __name__ == '__main__':
    tornado.options.parse_command_line()  # 获取命令行的参数 --port=1040 就能使用这个参数
    print(options.port)
    print(options.version)

    http_server = tornado.httpserver.HTTPServer(application)
    application.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()
import time
import tornado.ioloop
import tornado.web
import tornado.options
tornado.options.parse_command_line()


class SyncHandler(tornado.web.RequestHandler):
    def get(self):
        print "mmmm"
        time.sleep(10)
        self.write('AHandler Request')


def make_app():
    return tornado.web.Application([
        (r"/sync", SyncHandler),
    ], autoreload=True)


if __name__ == "__main__":
    app = make_app()
    app.listen(8003)
    tornado.ioloop.IOLoop.current().start()

附加:

httpclient包是tornaod自带的http客户端,你可以相称curl和urllib2,他们有的功能httpclient也都有的。
tornado的httpclient包,包含了两个模块,一个是同步的,一个是异步的。

http_client = httpclient.AsyncHTTPClient()
这个是异步非阻塞的 http客户端, 这种方法需要提供 callback,当然他的异步是在tornado的体系里面体现出来的。

http_client = httpclient.HTTPClient()
这个同步阻塞的 http客户端, 这个完全就是同步的,也就是说,他堵塞了后,别人就不能在访问了。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值