简体   繁体   English

Asyncio和无限循环

[英]Asyncio and infinite loop

@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())

Let's say i'm using websockets with asyncio. 假设我正在使用带有asyncio的websockets。 That means I recieve messages from websockets . 这意味着我收到来自websockets消息。 And when I recieve a message, I want to handle the message but I'm loosing all the async thing with my code. 当我收到消息时,我想处理消息但是我的代码丢失了所有异步的东西。 Because the yield from handle(message) is definetly blocking... How could I find a way to make it non-blocking ? 因为yield from handle(message)yield from handle(message)绝对阻塞......我怎么能找到一种方法使其无阻塞? Like, handle multiple messages in the same time. 比如,在同一时间处理多条消息。 Not having to wait the message to be handled before I can handle another message. 在我可以处理另一条消息之前,不必等待消息处理。

Thanks. 谢谢。

If you don't care about the return value from handle message, you can simply create a new Task for it, which will run in the event loop alongside your websocket reader. 如果你不关心handle消息的返回值,你可以简单地为它创建一个新的Task,它将在你的websocket阅读器旁边的事件循环中运行。 Here is a simple example: 这是一个简单的例子:

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

ensure_future will create a task and attach it to the default event loop. ensure_future将创建一个任务并将其附加到默认事件循环。 Since the loop is already running, it will get processed alongside your websocket reader in parallel. 由于循环已经运行,它将与您的websocket阅读器并行处理。 In fact, if it is a slow-running I/O blocked task (like sending an email), you could easily have a few dozen handle(message) tasks running at once. 实际上,如果它是一个运行缓慢的I / O阻塞任务(如发送电子邮件),您可以轻松地同时运行几十个句柄(消息)任务。 They are created dynamically when needed, and destroyed when finished (with much lower overhead than spawning threads). 它们在需要时动态创建,并在完成时销毁(比生成线​​程的开销低得多)。

If you want a bit more control, you could simply write to an asyncio.Queue in the reader and have a task pool of a fixed size that can consume the queue, a typical pattern in multi-threaded or multi-process programming. 如果你想要更多的控制,你可以简单地写入阅读器中的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))

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

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