Asyncio和无限循环

时间:2015-12-02 09:51:07

标签: python python-asyncio

@asyncio.coroutine
    def listener():
        while True:
            message = yield from websocket.recieve_message()
            if message:
                yield from handle(message)

loop = asyncio.get_event_loop()
loop.run_until_complete(listener())

让我们说我使用带有asyncio的websockets。这意味着我收到来自websockets的消息。当我收到消息时,我想处理消息,但是我的代码丢失了所有异步内容。因为yield from handle(message)绝对阻挡......我怎么能找到一种方法使其无阻塞?比如,在同一时间处理多条消息。在处理另一条消息之前,不必等待处理消息。

感谢。

1 个答案:

答案 0 :(得分:3)

如果您不关心句柄消息的返回值,您只需为它创建一个新的任务,它将在您的websocket阅读器旁边的事件循环中运行。这是一个简单的例子:

@asyncio.coroutine
def listener():
    while True:
        message = yield from websocket.recieve_message()
        if message:
            asyncio.ensure_future(handle(message))

ensure_future将创建一个任务并将其附加到默认事件循环。由于循环已经运行,它将与您的websocket阅读器并行处理。实际上,如果它是一个运行缓慢的I / O阻塞任务(如发送电子邮件),您可以轻松地同时运行几十个句柄(消息)任务。它们在需要时动态创建,并在完成时销毁(比产生线程的开销低得多)。

如果你想要更多的控制,你可以简单地写入阅读器中的asyncio.Queue并拥有一个可以使用队列的固定大小的任务池,这是多线程或多进程编程中的典型模式

@asyncio.coroutine
def consumer(queue):
    while True:
        message = yield from queue.get()
        yield from handle(message)

@asyncio.coroutine
def listener(queue):
    for i in range(5):
         asyncio.ensure_future(consumer(queue))
    while True:
        message = yield from websocket.recieve_message()
        if message:
            yield from q.put(message)

q = asyncio.Queue()
loop = asyncio.get_event_loop()
loop.run_until_complete(listener(q))