当前位置: 首页 > 知识库问答 >
问题:

编写一个tornado协同程序,该程序也会生成正常值

罗绪
2023-03-14

在Tornado中,我们可以使用coroutine decorator作为Python生成器灵活地编写一个异步函数,其中每个yield语句返回给调度器,最后的raise/return向调用者返回一个值。但是,有没有任何方法可以向调用者返回一系列值,其中穿插着异步调用?

例如,如何启用此同步功能:

def crawl_site_sync(rooturi):
    rootpage = fetch_page_sync(rooturi)
    links = extract_links(rootpage)
    for link in links:
        yield fetch_page_sync(link.uri)

…我可以这样称呼它:

for page in crawl_site_sync("http://example.com/page.html"):
    show_summary(page)

…进入Tornado中类似的异步函数?例如。:

@tornado.gen.coroutine
def crawl_site_async(rooturi):
    # Yield a future to the scheduler:
    rootpage = yield fetch_page_async(rooturi)
    links = extract_links(rootpage)
    for link in links:
        # Yield a future to the scheduler:
        sub_page = yield fetch_page_async(link.uri)
        # Yield a value to the caller:
        really_really_yield sub_page # ???

我该怎么称呼它呢?

for page in yield crawl_site_sync("http://example.com/page.html"):
    # This won't work, the yield won't return until the entire
    # coroutine has finished, and it won't give us an iterable.
    show_summary(page)

我可以想出一些方法来完成它,但是所有这些方法都涉及到改变调用站点和函数的程度,以至于它完全失去了异步版本看起来与同步版本非常相似的好处,并且它不再干净地组成。我觉得我一定错过了一个技巧。有没有办法同时使用Python生成器作为懒惰计算值的序列和龙卷风协程?

共有1个答案

万博涛
2023-03-14

我会使用来自Toro的队列,它是为协同程序设计的,以便像这样进行协作。下面是一个简单的例子:

from tornado.ioloop import IOLoop
from tornado import gen
from tornado.httpclient import AsyncHTTPClient
from toro import Queue

q = Queue(maxsize=1)


@gen.coroutine
def consumer():
    item = yield q.get()
    while item:
        print item
        item = yield q.get()


@gen.coroutine
def producer():
    try:
        client = AsyncHTTPClient()
        for url in [
                'http://tornadoweb.org',
                'http://python.org',
                'http://readthedocs.org']:
            response = yield client.fetch(url)
            item = (url, len(response.body))
            yield q.put(item)

        # Done.
        q.put(None)
    except Exception:
        IOLoop.current().stop()
        raise

future = producer()
IOLoop.current().run_sync(consumer, timeout=20)

Toro的文档中有一个更详细的网络爬虫示例,如下所示:

https://toro.readthedocs.org/en/stable/examples/web_spider_example.html

 类似资料:
  • 请为我们第一个程序 理所当然的 Hello, World! 做好准备。 1: %include 'system.inc' 2: 3: section .data 4: hello db 'Hello, World!', 0Ah 5: hbytes equ $-hello 6: 7: section .text 8: global _start 9: _st

  • 本文向大家介绍编写一个在C和C ++编程中产生不同结果的程序,包括了编写一个在C和C ++编程中产生不同结果的程序的使用技巧和注意事项,需要的朋友参考一下 编写一个可编译并在c和c ++中运行并产生不同结果的程序。 使用c和c ++进行编译时,有多种类型的程序会给出不同的结果。 一世。使用字符字面量-c和c ++都以不同的方式对待字符。在C中,它们被视为整数文字,而在C ++中,它们被视为字符。

  • 问题内容: 我有一个python生成器函数,可以生成文本块。我想为子类编写一个方法,该方法将遍历生成器,并随即将大块写入响应。 由于这是Tornado,并且由于生成器可能要花一秒钟的时间来处理,所以我认为最好使处理程序异步,使用此生成器作为协程并将控制权在每个块之后传递给IOLoop。但是,我无法做到这一点。 这是我的示例(阻止)代码: 如何使此处理程序异步工作? 问题答案: 这是您所描述内容的基

  • 这本书你已经完成一半了,所以你需要做一个期中检测。期中检测中你需要重新构建一个我特地为本书编写的软件,叫做devpkg。随后你需要以一些方式扩展它,并且通过编写一些单元测试来改进代码。 注 我在一些你需要完成的练习之前编写了这个练习。如果你现在尝试这个练习,记住软件可能会含有一些bug,你可能由于我的错误会产生一些问题,也可能不知道需要什么来完成它。如果这样的话,通过help@learncodet

  • 问题内容: 我正在寻找一个完全由Java驱动的免费跨平台安装程序生成器(这意味着工作流和插件是用Java编写的)。理想情况下,安装程序应按需下载JRE,而不是将其直接捆绑到安装程序中。这样的东西已经存在了吗? 请注意,InstallAnywhere不再提供免费版本。 问题答案: IzPack 抗原 Launch4J 蚂蚁 Java服务包装器 提起Java安装程序 JSmooth VA安装 pack

  • 主要内容:什么是协同(coroutine)?,coroutine_test.lua 文件,实例,生产者-消费者问题,实例什么是协同(coroutine)? Lua 协同程序(coroutine)与线程比较类似:拥有独立的堆栈,独立的局部变量,独立的指令指针,同时又与其它协同程序共享全局变量和其它大部分东西。 协同是非常强大的功能,但是用起来也很复杂。 线程和协同程序区别 线程与协同程序的主要区别在于,一个具有多个线程的程序可以同时运行几个线程,而协同程序却需要彼此协作的运行。 在任一指定时刻只有