为什么需要等待协程?

WoJ*_*WoJ 3 python asynchronous python-3.x python-asyncio

我从websockets开始,并且asyncio很难理解背后的逻辑。过去,我在Python上使用过线程,而在Javascript上使用过AJAX调用(因此,我对多线程(绑定了I / O)和可异步执行结果的过程的概念有所了解)。

示例服务器如下。我的目的是提供一个websocket连接和两个函数,每10秒将调用一次,而无需等待结果(因此,每10秒恰好一个调用,而不管这些函数要花多长时间)。

import time
import arrow
import websockets
import asyncio

async def time1(websocket):
    # simulation of a time intensive operation
    time.sleep(2)
    msg = '1 ' + arrow.now()
    print(msg)
    websocket.send(msg)

async def time2(websocket):
    # simulation of a time intensive operation
    time.sleep(3)
    msg = '2 ' + arrow.now()
    print(msg)
    websocket.send(msg)

async def update_info(websocket, path):
    while True:
        now = arrow.now()
        if not now.second % 10:
            time1(websocket)
        if not now.second % 10:
            time2(websocket)

        time.sleep(1)

start_server = websockets.serve(update_info, 'localhost', 5678)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
Run Code Online (Sandbox Code Playgroud)

客户端连接后,我希望在接下来的整整10秒内启动这些功能。它们将在2到3秒后完成,然后在接下来的整整10秒钟内发射,依此类推。

我得到的是

D:/Dropbox/dev/domotique/webserver.py:708: RuntimeWarning: coroutine 'time1' was never awaited
  time1(websocket)
D:/Dropbox/dev/domotique/webserver.py:710: RuntimeWarning: coroutine 'time2' was never awaited
  time2(websocket)
Run Code Online (Sandbox Code Playgroud)

并且没有发送或打印任何消息。

为什么我要await为协程?我想将它们分解成表格,update_info然后忘记它们(=让它们进行处理,然后让它们通过websocket发送数据)。我的方法有什么问题?

son*_*olo 5

await有效地将等待的协程耦合到事件循环,等待它完成,然后继续。如果您不await使用协程,则不会发生这种情况。

如果您只想在后台运行协程(更像是Task),请使用asyncio.ensure_future(my_coroutine()),它将剥离a Task并让您继续进行其他操作。

编辑:异步的新手要注意的是,如果您有多个正在运行的任务,那么除非任务具有内部await语句,否则事件循环将卡在该任务中,除非它返回。事件循环给人一次做两件事的印象的方法是在不同的代码位之间来回移动。该await声明是其中的事件循环可以做杂耍点。因此,在等待一段代码时,另一段代码可以继续运行。一旦另一段代码命中await,则阵容中的下一段代码将继续执行,依此类推。换句话说,请注意awaits将代码放置在何处,并以长久的方式设计代码运行中的代码不会阻止更多受益于异步的动态组件。