版权声明:本文为博主原创文章,未经博主允许不得转载。 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协程使用和原理(三)的更多相关文章

  1. tornado用户指引(二)------------tornado协程实现原理和使用(一)

    摘要:Tornado建议使用协程来实现异步调用.协程使用python的yield关键字来继续或者暂停执行,而不用编写大量的callback函数来实现.(在linux基于epoll的异步调用中,我们需要 ...

  2. tornado用户指引(三)------tornado协程使用和原理(二)

    Python3.5  async和await async和await是python3.5引入的2个新的关键字(用这两个关键字编写的函数也称之为"原生协程"). 从tornado4. ...

  3. python并发编程之进程、线程、协程的调度原理(六)

    进程.线程和协程的调度和运行原理总结. 系列文章 python并发编程之threading线程(一) python并发编程之multiprocessing进程(二) python并发编程之asynci ...

  4. GO GMP协程调度实现原理 5w字长文史上最全

    1 Runtime简介 Go语言是互联网时代的C,因为其语法简洁易学,对高并发拥有语言级别的亲和性.而且不同于虚拟机的方案.Go通过在编译时嵌入平台相关的系统指令可直接编译为对应平台的机器码,同时嵌入 ...

  5. 深入浅出!从语义角度分析隐藏在Unity协程背后的原理

    Unity的协程使用起来比较方便,但是由于其封装和隐藏了太多细节,使其看起来比较神秘.比如协程是否是真正的异步执行?协程与线程到底是什么关系?本文将从语义角度来分析隐藏在协程背后的原理,并使用C++来 ...

  6. Golang源码探索(二) 协程的实现原理

    Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱, 虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻 ...

  7. Golang源码探索(二) 协程的实现原理(转)

    Golang最大的特色可以说是协程(goroutine)了, 协程让本来很复杂的异步编程变得简单, 让程序员不再需要面对回调地狱,虽然现在引入了协程的语言越来越多, 但go中的协程仍然是实现的是最彻底 ...

  8. 协程概念,原理及实现(c++和node.js实现)

    协程 什么是协程 wikipedia 的定义: 协程是一个无优先级的子程序调度组件,允许子程序在特点的地方挂起恢复. 线程包含于进程,协程包含于线程.只要内存足够,一个线程中可以有任意多个协程,但某一 ...

  9. tornado 协程的实现原理个人理解;

    tornado实现协程的原理主要是利用了(1)python里面的generator (2)future类和ioloop相互配合,两者之间的相互配合是通过gen.coroutine装饰器来实现的: 具体 ...

随机推荐

  1. C中atoi和strcpy的自定义实现

    这是两道经常考到的笔试题,看似简单的实现,其实专注到细节,还是有很多需要注意扣分的地方. atoi实现: #include <iostream> #include<ctype.h&g ...

  2. css层叠性和继承性

    1.了解css层叠性 层叠性是什么?就是解决处理css选择器和属性冲突的能力.css的选择器权重是分大小,就是当多个选择器都选中了同一个标签时,听谁的??? 标签选择器 < 类选择器 < ...

  3. C# GDI+ 利用 Rectangle GraphicsPath 判断 矩形或多边形 图形关系

    最近在做一些简单的图像对比工作,总结了一些GDI+对象的使用方式,记录下来共享给大家使用. 判断Rectangl与多边形的关系 /// <summary> /// 是否包含输入范围 /// ...

  4. 生成证书,用于签名Android应用

    1. keytool 命令 1)使用JDK中的一个命令keytool,都有哪些命令呢,使用 keytool -help 进行查看 2)本次使用 keytool -genkeypair 命令生成签名,查 ...

  5. 工作好搭档(一):松林 SL-B3 人体工学椅

    本人从事码农这行职业,已经整整十年零九天,十年一觉如旧梦,仿佛昨天还在SARS. 2008年,我累到腰痛,脖子痛,怎么休息也不见好,去中医院检查,医生诊断,坐的太久,坐姿不对,运动少,轻度颈椎,腰肌劳 ...

  6. Oracle练习详解

    --1.查询emp表,显示薪水大于2000,且工作类别是MANAGER的雇员信息 select * from emp where sal > 2000and job = 'MANAGER'; - ...

  7. React v15.5.0更新说明 & v16.0.0更新预告

    React今日发布了15.5.0版本,同时这也将是以15开头的最后一个版本,下一次发布,我们将迎来React 16.0.0 在15.5.0这一版本中,主要有以下两处改动: 独立React.PropTy ...

  8. 【CSS单位】px、em、rem

    1.PX为单位 在Web页面初期制作中,我们都是使用“px”来设置我们的文本,因为他比较稳定和精确.但是这种方法存在一个问题,当用户在浏览器中浏览我们制作的Web页面时,他改变了浏览器的字体大小,这时 ...

  9. css3中的变形 transform详解

    一.变形-旋转 ratate()函数 通过指定的角度参数使元素相对原点进行旋转.它主要在二维空间内进行操作,设置一个角度值,用来指定旋转的幅度.如果这个值为正值,元素相对原点中心顺时针旋转:如果这 个 ...

  10. 记录一次Git问题及其解决方案

    错误信息:fatal: refusing to merge unrelated histories 错误产生背景:我将原先测试的项目本地删除后提交,然后将新的项目按照git的提交步骤进行提交,在最后一 ...