tornado 11 异步编程
tornado 11 异步编程
一、同步与异步
同步
#含义:指两个或两个以上随时间变化的量在变化过程中保持一定的相对关系 #现象:有一个共同的时钟,按来的顺序一个一个处理 #直观感受:需要等待,效率低下
异步
#含义:双方不需要共同的时钟,就是接收方不知道发送方什么时候发送,所以在发送的信息中就要有提示接收方开始接受的信息,如开始位,同时在结束时有结束位 #现象:没有共同的时钟,不考虑顺序来了就处理 #直观感受:不需要等待,效率高
二、阻塞与非阻塞
阻塞调用
#含义:阻塞调用是指在调用结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,CPU不会给线程分配时间片,即线程暂停运行)。函数只有在得到结果之后才会返回 #现象:读套接字是没用数据等数据来,写套接字时写不下了也一直等,等能写下了往下写(套接字被写满的原因不在本地,在于网络另一头的套接字被写满了来不及读出去,导致本地的套接字内容发不出来,堵住了) #直观感受:执着
非阻塞调用
#含义:非阻塞调用是指没有调用结果立即返回,当前线程不被挂起,可以继续做其他工作 #现象:读套接字是没有数据,不等直接返回干别得事情去了,写套接字写不下了也不写了,直接返回干别的事情去了 #直观感受:勤奋
三、异步编程
#tornado是单线程的,一次只能处理一个请求;但是由于他是异步的,所以是高并发的 #那么在tornado中,同时有多个请求发送过来时,而且其中还有请求发生阻塞,会产生什么样的后果呢?
#在实现第四种异步方法的时候需要导入两个模块 futures requests
import time
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define,options
from tornado.web import authenticated
import tornado.websocket
import tornado.httpclient
import tornado.gen
from tornado.concurrent import run_on_executor
from concurrent.futures import ThreadPoolExecutor
import requests
import util.ui_methods
import util.ui_modules
from data.user_modules import User #导入module包
from pycket.session import SessionMixin
import datetime define('port',default=8080,help = 'run port',type=int) class BaseHandler(tornado.web.RequestHandler,SessionMixin):
def get_current_user(self):
current_user = self.session.get('user')
if current_user:
return current_user
return None class AbcHandler(BaseHandler):
def get(self):
self.write('abc ok') class SyncHandler(BaseHandler):
def get(self):
client = tornado.httpclient.HTTPClient()
response = client.fetch('http://127.0.0.1:8080/sync?id=2') #这是模拟阻塞的接口,该接口代码里面有sleep用来模拟阻塞
print(response)
self.write(response.body) #1、通过回调函数实现异步
class CallbcakHandler(BaseHandler): #这便是异步的方法,在阻塞的时候就直接处理其他的请求
@tornado.web.asynchronous #必须得装上装饰器
def get(self):
client = tornado.httpclient.AsyncHTTPClient()
response = client.fetch('http://127.0.0.1:8080/sync?id=2',callback=self.on_response) #当这个地方发生阻塞时,并没有在这个地方等待,而是后面的全部处理完了才来处理这个
self.write('ok') #这便是通过回调函数实现异步,先出现ok,在回到上面 def on_response(self,res):
print(res)
self.write(res.body)
self.finish() #在这个回调函数中必须加上finish,不加上的话就会不知道上面的接口函数什么时候结束 #2、通过协程实现异步
class GenHandler(BaseHandler):
@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:8080/sync?id=2') #yield生成器,有等待、暂停的功能
self.write(response.body) #3、通过协程实现异步(自定义函数) 更加灵活
class FuncHandler(BaseHandler):
@tornado.web.asynchronous
@tornado.gen.coroutine #协程
def get(self):
response = yield self.func()
self.write(response.body) @tornado.gen.coroutine
def func(self):
client = tornado.httpclient.AsyncHTTPClient()
response = yield tornado.gen.Task(client.fetch, 'http://127.0.0.1:8080/sync?id=2') # yield生成器,有等待、暂停的功能
raise tornado.gen.Return(response) #4、通过requests包来实现异步,都是使用装饰器
class MyHandler(BaseHandler):
executor = ThreadPoolExecutor()
@tornado.web.asynchronous
@tornado.gen.coroutine
def get(self):
response = yield self.func()
self.write(response.text) @run_on_executor
def func(self):
res = requests.get('http://127.0.0.1:8080/sync?id=2')
return res application = tornado.web.Application(
handlers=[
(r'/abc',AbcHandler),
(r'/sync', SyncHandler),
(r'/call', CallbcakHandler),
(r'/gen', GenHandler),
(r'/func', FuncHandler),
(r'/my', MyHandler), ],
template_path = 'templates',
static_path= 'static',
autoescape = None,
ui_methods=util.ui_methods,
ui_modules=util.ui_modules,
cookie_secret = 'lidang',
login_url = '/login',
pycket = {
'engine':'redis',
'storage':{
'host':'localhost',
'port':6379,
'db_sessions':5,
'db_notifications':11,
'max_connections':2 ** 33,
},
'cookie':{
'expires_days':38,
'max_age':100
}
},
debug=True
) if __name__ == '__main__':
tornado.options.parse_command_line()
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
tornado 11 异步编程的更多相关文章
- 使用tornado的gen.coroutine进行异步编程
在tornado3发布之后,强化了coroutine的概念,在异步编程中,替代了原来的gen.engine, 变成现在的gen.coroutine.这个装饰器本来就是为了简化在tornado中的异步编 ...
- C++11 使用异步编程std::async和std::future
先说明一点:std::asyanc是std::future的高级封装, 一般我们不会直接使用std::futrue,而是使用对std::future的高级封装std::async. 下面分别说一下. ...
- 《深入理解ES6》笔记—— Promise与异步编程(11)
为什么要异步编程 我们在写前端代码时,经常会对dom做事件处理操作,比如点击.激活焦点.失去焦点等:再比如我们用ajax请求数据,使用回调函数获取返回值.这些都属于异步编程. 也许你已经大概知道Jav ...
- 深入理解 Python 异步编程(上)
http://python.jobbole.com/88291/ 前言 很多朋友对异步编程都处于"听说很强大"的认知状态.鲜有在生产项目中使用它.而使用它的同学,则大多数都停留在知 ...
- C#与C++的发展历程第三 - C#5.0异步编程巅峰
系列文章目录 1. C#与C++的发展历程第一 - 由C#3.0起 2. C#与C++的发展历程第二 - C#4.0再接再厉 3. C#与C++的发展历程第三 - C#5.0异步编程的巅峰 C#5.0 ...
- [C#] 走进异步编程的世界 - 开始接触 async/await
走进异步编程的世界 - 开始接触 async/await 序 这是学习异步编程的入门篇. 涉及 C# 5.0 引入的 async/await,但在控制台输出示例时经常会采用 C# 6.0 的 $&qu ...
- 深入解析js异步编程利器Generator
我们在编写Nodejs程序时,经常会用到回调函数,在一个操作执行完成之后对返回的数据进行处理,我简单的理解它为异步编程. 如果操作很多,那么回调的嵌套就会必不可少,那么如果操作非常多,那么回调的嵌套就 ...
- [C#] 走进异步编程的世界 - 剖析异步方法(上)
走进异步编程的世界 - 剖析异步方法(上) 序 这是上篇<走进异步编程的世界 - 开始接触 async/await 异步编程>(入门)的第二章内容,主要是与大家共同深入探讨下异步方法. 本 ...
- [C#] 走进异步编程的世界 - 剖析异步方法(下)
走进异步编程的世界 - 剖析异步方法(下) 序 感谢大家的支持,这是昨天发布<走进异步编程的世界 - 剖析异步方法(上)>的补充篇. 目录 异常处理 在调用方法中同步等待任务 在异步方法中 ...
随机推荐
- Celery 与 Flask 大型程序结构的结合
:first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; m ...
- 【原创】9. MYSQL++中的Field、FieldNames以及FieldTypes类型
mysqlpp::Field其实使用的并不多,主要在于Result.h中ResultBase以及他的派生类型(UseQueryResult和StoreQueryResult)的几个获取下一个field ...
- wangEditor富文本编辑器
设置好了是这样的, 有一个ID问content的编辑框,方便获取,这里的富文本编辑器的版本是2.2 官方文档说3就不支持textarea了 导入一下css 记得css文件夹下应该又3个文件,虽然没有直 ...
- selenium2 用Yaml文件进行元素管理 (五)
比如界面有一个按钮,id号是test.如果进行对象化的话,就是test.click就可以了.不用每次都要去创建test对象.如果id号变了,我们也只需要改一下test的名称就行了. 使用Yaml需要用 ...
- opennebula模板对照比较
良好模板 有问题模板
- SHELL读取 ini 格式文件做配置文件
ini文件格式一般都是由节.键.值三部分组成 格式: [第一节 ] 第一个键 = 值 第二个键 = 第二个值 [第二节 ] 第一个键 = val1,val2,val3 例子: [COM] KINGGO ...
- Web服务器父与子 Apache和Tomcat区别(转)
From http://developer.51cto.com/art/201007/210894.htm 熟悉三国的朋友都知道曹操,曹操有二十五个儿子,其中最得曹操宠爱的是曹丕.曹植.曹彰三个,曹丕 ...
- IP协议、ARP协议等之温故知新
今天才知道: 1.IP协议的固定部分长度为20字节.(貌似有一家运维工程师面试我的时候,问过我这个问题呢.) 2.IP数据包首部中的协议?? 答:协议:占8位,指出此数据报携带的数据使用何种协议以便目 ...
- Spring.Web.Mvc 注入(控制器属性注入)
1.web.config配置 <?xml version="1.0" encoding="utf-8"?><!-- 有关如何配置 ASP.NE ...
- 运行maven build报错No goals have been specified for this build.
运行maven报错: [ERROR] No goals have been specified for this build. You must specify a valid lifecycle p ...