为什么我需要等待协程?

时间:2016-12-12 17:08:17

标签: python python-3.x asynchronous 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()

我预计,一旦客户端连接,在接下来的整整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)

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

为什么我必须await为协同程序?我想以update_info形式触发它们并忘记它们(=让它们处理它们并让它们通过websocket发送数据)。 我的方法出了什么问题?

1 个答案:

答案 0 :(得分:5)

await有效地将等待的协程耦合到事件循环,等待它完成,然后继续。如果你没有await协程,那么这不会发生。

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

编辑:异步新手的一个问题是,如果你有多个正在运行的任务,那么除非任务有内部await语句,否则事件循环将会遇到该任务,除非它返回。事件循环给人的印象是一次做两件事就是在不同的代码之间来回徘徊。 await语句是事件循环可以进行杂乱的点。因此,当一段代码正在等待时,另一段代码将继续运行。一旦其他代码点击了await,那么该阵容中的下一段代码就会获得批准等等。换句话说,请注意放置awaits的位置,并设计你的代码,使长时间运行的代码不会阻止从异步中受益的更动态的组件。