tornado用户指引(四)------tornado协程使用和原理(三)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/happyAnger6/article/details/51291221
几种常用的协程方式:
1.回调函数
如果你要执行的异步代码是基于回调函数而不是基于Future的,你可以将异步代码通过Task装饰起来。这样Task装饰器会为你添加callback并返回一个Future,这样你就可以用yield来执行异步代码。
@gen.coroutine
def call_task():
# Note that there are no parens on some_function.
# This will be translated by Task into
# some_function(other_args, callback=callback)
yield gen.Task(some_function, other_args)
在some_function里,你可以执行基于回调函数的异步代码。gen.Task会为你设置好一个callback并通过callback参数传递给some_function,你在some_function内部将callback传递给异步代码所需的callback即可。
2.调用阻塞函数
调用阻塞函数最简单的办法是通过使用ThreadPoolExecutor,它会返回一个Future.
thread_pool = ThreadPoolExecutor(4)
@gen.coroutine
def call_blocking():
yield thread_pool.submit(blocking_func, args)
3.并行
coroutine装饰器能够识别Future的列表或字典,能够并行执行它们并等待全部完成。
@gen.coroutine
def parallel_fetch(url1, url2):
resp1, resp2 = yield [http_client.fetch(url1),
http_client.fetch(url2)]
@gen.coroutine
def parallel_fetch_many(urls):
responses = yield [http_client.fetch(url) for url in urls]
# responses is a list of HTTPResponses in the same order
@gen.coroutine
def parallel_fetch_dict(urls):
responses = yield {url: http_client.fetch(url) for url in urls}
# responses is a dict {url: HTTPResponse}
4.在yield前插入其它代码
有时候,你需要暂存一个Future而不立即yield它。在此之前可以执行一些其它操作。
@gen.coroutine
def get(self):
fetch_future = self.fetch_next_chunk()
while True:
chunk = yield fetch_future #这里对取到的Future执行yield
if chunk is None: break
self.write(chunk)
fetch_future = self.fetch_next_chunk() #先得到Future而不立刻对其yield
yield self.flush()
5.循环
由于在python没有办法对for和while循环的每次迭代yield并同时获取结果,所以在循环中使用协程需要一些技巧。
你需要将循环条件和访问结果分开进行,下面的例子演示了这一点:
motor是一个mongodb的python api,它的实现也是基于协程方式,可以十分方便地在tornado中使用它。
import motor
db = motor.MotorClient().test
@gen.coroutine
def loop_example(collection):
cursor = db.collection.find()
while (yield cursor.fetch_next):
doc = cursor.next_object()
6.在后台执行
PeriodicCallback(用于定期地执行一个函数)在协程中并不十分常用。你可以在协程中使用一个循环,在循环中使用tornado.gen.sleep达到同样的效果。
@gen.coroutine
def minute_loop():
while True:
yield do_something()
yield gen.sleep(60)
# Coroutines that loop forever are generally started with
# spawn_callback().
IOLoop.current().spawn_callback(minute_loop)
有时候,你可能需要执行一个更复杂的循环逻辑。比如,上面的例子中循环体每60+N s运行一次,N是do_something()函数执行的时间.如果你想精确控制每次循环执行时间为60s,你可以像下面这样做:
@gen.coroutine
def minute_loop2():
while True:
nxt = gen.sleep(60) # 启动一个定时器并不yield它.
yield do_something() # 在执行定时器的同时执行函数
yield nxt # 此时再等待定时器超时.
---------------------
作者:self-motivation
来源:CSDN
原文:https://blog.csdn.net/happyAnger6/article/details/51291221
版权声明:本文为博主原创文章,转载请附上博文链接!
tornado用户指引(四)------tornado协程使用和原理(三)的更多相关文章
- tornado用户指引(二)------------tornado协程实现原理和使用(一)
摘要:Tornado建议使用协程来实现异步调用.协程使用python的yield关键字来继续或者暂停执行,而不用编写大量的callback函数来实现.(在linux基于epoll的异步调用中,我们需要 ...
- tornado用户指引(三)------tornado协程使用和原理(二)
Python3.5 async和await async和await是python3.5引入的2个新的关键字(用这两个关键字编写的函数也称之为"原生协程"). 从tornado4. ...
- python并发编程之进程、线程、协程的调度原理(六)
进程.线程和协程的调度和运行原理总结. 系列文章 python并发编程之threading线程(一) python并发编程之multiprocessing进程(二) python并发编程之asynci ...
- GO GMP协程调度实现原理 5w字长文史上最全
1 Runtime简介 Go语言是互联网时代的C,因为其语法简洁易学,对高并发拥有语言级别的亲和性.而且不同于虚拟机的方案.Go通过在编译时嵌入平台相关的系统指令可直接编译为对应平台的机器码,同时嵌入 ...
- 深入浅出!从语义角度分析隐藏在Unity协程背后的原理
Unity的协程使用起来比较方便,但是由于其封装和隐藏了太多细节,使其看起来比较神秘.比如协程是否是真正的异步执行?协程与线程到底是什么关系?本文将从语义角度来分析隐藏在协程背后的原理,并使用C++来 ...
- Golang源码探索(二) 协程的实现原理
Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱, 虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻 ...
- Golang源码探索(二) 协程的实现原理(转)
Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱,虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻底 ...
- 协程概念,原理及实现(c++和node.js实现)
协程 什么是协程 wikipedia 的定义: 协程是一个无优先级的子程序调度组件,允许子程序在特点的地方挂起恢复. 线程包含于进程,协程包含于线程.只要内存足够,一个线程中可以有任意多个协程,但某一 ...
- tornado 协程的实现原理个人理解;
tornado实现协程的原理主要是利用了(1)python里面的generator (2)future类和ioloop相互配合,两者之间的相互配合是通过gen.coroutine装饰器来实现的: 具体 ...
随机推荐
- windows定位dll的搜索顺序
原文:http://blog.csdn.net/zzxian/article/details/6429293 Visual C++ Windows 用来定位 DLL 的搜索路径 通过隐式和显式链接,W ...
- 【Markdown】Latex基本语法
Latex基本语法 注意点:Markdown 斜杠/ 转义字符! LaTeX 是大神Leslie Lamport 的杰作,该神是2013年图灵奖的获得者,感兴趣可以去瞻仰一下神人的相关著述: http ...
- CFileDialog 多文件选择
CString pathName = _T(""); CString fileName = _T(""); CString strMulfilepath = _ ...
- java学习笔记之Java的特点
Java在如今的发展趋势而言,一直都是处于流行的原因自然也是随之而存在的. java的特点如下几个方面: 1.简单性 Java 实际上是一个 C++去掉了复杂性之后的简化版.如果读者没有编程经验,会发 ...
- C# Request获取URL常见用法
如果测试的url地址是http://www.test.com/testweb/default.aspx, 结果如下: Request.ApplicationPath: /testweb Request ...
- PLSQL使用绑定变量
想对一个sql做10046trace,结果因为10g数据库无法对sql_id做,只能使用绑定变量的方法,下面sql是如何使用绑定变量运行sql的语句 declare v_sql VARCHAR2( ...
- css z-index层重叠顺序
一.z-index语法与结构 z-index 跟具体数字 如:div{z-index:100}注意:z-index的数值不跟单位. z-index的数字越高越靠前,并且值必须为整数和正数(正数的整数) ...
- python .loc vs .iloc区别
1.loc意义:通过行标签索引行数据 例: loc[n]表示索引的是第n行(index 是整数) loc[‘d’]表示索引的是第’d’行(index 是字符) 2. .iloc :通过行号获取行数 ...
- Avito Cool Challenge 2018 B. Farewell Party 【YY】
传送门:http://codeforces.com/contest/1081/problem/B B. Farewell Party time limit per test 1 second memo ...
- ASP.NET Web API编程——构建api帮助文档
1 概要 创建ASP.NET Web Api 时模板自带Help Pages框架. 2 问题 1)使用VS创建Web Api项目时,模板将Help Pages框架自动集成到其中,使得Web Api项目 ...