简体   繁体   English

了解asyncio已经永远运行循环和待处理任务

[英]understanding asyncio already running forever loop and pending tasks

I'm having problems understanding how to pend a new task to an already running event loop. 我在理解如何将新任务挂起到已经运行的事件循环时遇到了问题。

This code: 这段代码:

import asyncio
import logging

@asyncio.coroutine
def blocking(cmd):
    while True:
        logging.info("in blocking coroutine")
        yield from asyncio.sleep(0.01)
        print("ping")

def main():
    logging.info("in main funciton")
    loop = asyncio.get_event_loop()
    logging.info("new loop created")
    logging.info("loop running forever")
    loop.run_forever()
    asyncio.async(blocking("ls"))

logging.basicConfig(level = logging.INFO)
main()

Changing run_forever() to run_until_complete(asyncio.async(blocking("ls")) works fine. But I'm really confused - why I can't pend a task on the already running loop? run_forever()更改为run_until_complete(asyncio.async(blocking("ls"))工作正常。但我真的很困惑 - 为什么我不能在已经运行的循环上挂起任务?

The problem is that the call to loop.run_forever() blocks; 问题是对loop.run_forever()的调用阻塞; it starts the event loop, and won't return until you explicitly stop the loop - hence the forever part of run_forever . 它启动事件循环,直到你明确地停止循环才会返回 - 因此是run_foreverforever部分。 Your program never explicitly stops the event loop, so your asyncio.async(blocking("ls")) call is never reached. 您的程序从不显式停止事件循环,因此永远不会到达您的asyncio.async(blocking("ls"))调用。

Using asyncio.async to add a new task to an already running loop is fine, you just need to make sure the function is actually called from inside a coroutine or callback inside the event loop. 使用asyncio.async将新任务添加到已经运行的循环中是很好的,您只需要确保该函数实际上是从事件循环内的协同程序或回调内部调用的。 Here are some examples: 这里有些例子:

Schedule blocking to run as soon as the event loop starts: 安排blocking在事件循环开始后立即运行:

def main():
    logging.info("in main funciton")
    loop = asyncio.get_event_loop()
    logging.info("new loop created")
    logging.info("loop running forever")
    asyncio.async(blocking("ls"))
    loop.run_forever()

Schedule blocking from a callback executed by the event loop: 安排blocking事件循环执行的回调:

def start_blocking():
    asyncio.async(blocking("ls"))

def main():
    logging.info("in main funciton")
    loop = asyncio.get_event_loop()
    logging.info("new loop created")
    logging.info("loop running forever")
    loop.call_soon(start_blocking)  # Calls start_blocking once the event loop starts
    loop.run_forever()

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

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