繁体   English   中英

Python 上的非阻塞生成器

[英]Non-blocking generator on Python

我在 QT 应用程序中使用来自请求模块的生成器函数,与请求流示例中的几乎相同:

import json
import requests

def get_stream():
    r = requests.get('http://httpbin.org/stream/20', stream=True)
    for line in r.iter_lines():
        if line:
            yield json.loads(line)

def consume_stream():
    for message in get_stream():
       #do something

然而,当没有传入的响应(来自 Twitters Streaming API 的不规则传入的推文)时,生成器get_stream将阻塞consume_stream方法。

这可能发生在任何情况下,生成器不会立即让步,而是必须等待传入的消息等,因此会阻塞消费者。

Python中是否有任何模式可以以非阻塞方式使用生成器,即如果生成器产生,则处理它的结果,否则做其他事情直到下一个结果出现?

看看生产者-消费者模式 它通常使用Queue在 python 中实现。

生产者,通常在一个线程或另一个进程中运行( Queue支持),只是将消息放入队列中。 消费者,只要有感觉,就会从队列中弹出消息。 此操作支持timeout参数。

正如 Simeon 在评论中所问的那样,它不能像您在示例中描述的那样简单。 有很多细节你必须注意。 根据您的用例,有不同的解决方案,或多或少有意义。 您没有详细说明您真正想做的事情,所以我只会将您发送到http://twistedmatrix.com/trac/wiki/QTReactor作为示例。 有不同的解决方案/框架可以实现异步消息队列。 我认为,这就是你要找的。

如果您控制生成器函数,一种解决方案是让它在超时后抛出异常。 也许是这样的:

def get_stream(timeout=None):
    while message=read_message(timeout=timout):
        yield message

如果发生超时条件,则让 read_message 抛出 TimeOutException 或其他内容。

当然,您仍然需要处理何时/如何重试/恢复的后勤工作。

您可以从 python 3.6 https://www.python.org/dev/peps/pep-0525/ 开始使用异步生成器

import json
import requests

async def get_stream():
    r = requests.get('http://httpbin.org/stream/20', stream=True)
    for line in r.iter_lines():
        if line:
            yield json.loads(line)

async def consume_stream():
   await for message in get_stream():
       #do something

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM