python协程asyncio 应用_Python-如何使用asyncio同时运行多个协程?
TL;DR使用^{}同時運行多個協程。Maybe this scenario requires a framework based on events/callbacks rather than one based on coroutines? Tornado?
不,你不需要其他框架。異步應用程序與同步應用程序的整體思想是,在等待結果時,它不會阻塞。不管它是如何實現的,使用協程或回調。I mean, because connection_handler is constantly waiting for incoming messages, the server can only take action after it has received a message from the client, right? What am I missing here?
在同步應用程序中,您將編寫類似msg = websocket.recv()的內容,這將阻塞整個應用程序,直到您收到消息為止(如您所述)。但在異步應用程序中則完全不同。
當你做msg = yield from websocket.recv()時,你會說:暫停connection_handler()的執行,直到websocket.recv()產生某些結果。在coroutine中使用yield from將控制返回到事件循環,以便在等待websocket.recv()的結果時可以執行其他一些代碼。請參閱documentation以更好地了解協同工作的工作原理。Let's say we – additionally – wanted to send a message to the client whenever some event happens. For simplicity, let's send a message periodically every 60 seconds. How would we do that?
在對starting event loop執行阻塞調用之前,可以使用^{}運行任意數量的協程。import asyncio
import websockets
# here we'll store all active connections to use for sending periodic messages
connections = []
@asyncio.coroutine
def connection_handler(connection, path):
connections.append(connection) # add connection to pool
while True:
msg = yield from connection.recv()
if msg is None: # connection lost
connections.remove(connection) # remove connection from pool, when client disconnects
break
else:
print('< {}'.format(msg))
yield from connection.send(msg)
print('> {}'.format(msg))
@asyncio.coroutine
def send_periodically():
while True:
yield from asyncio.sleep(5) # switch to other code and continue execution in 5 seconds
for connection in connections:
print('> Periodic event happened.')
yield from connection.send('Periodic event happened.') # send message to each connected client
start_server = websockets.serve(connection_handler, 'localhost', 8000)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.async(send_periodically()) # before blocking call we schedule our coroutine for sending periodic messages
asyncio.get_event_loop().run_forever()
下面是一個示例客戶機實現。它要求您輸入名稱,從echo服務器接收它,等待來自服務器的另外兩條消息(這是我們的周期性消息)并關閉連接。import asyncio
import websockets
@asyncio.coroutine
def hello():
connection = yield from websockets.connect('ws://localhost:8000/')
name = input("What's your name? ")
yield from connection.send(name)
print("> {}".format(name))
for _ in range(3):
msg = yield from connection.recv()
print("< {}".format(msg))
yield from connection.close()
asyncio.get_event_loop().run_until_complete(hello())
要點:在Python 3.4.4中,asyncio.async()被重命名為^{}。
調度delayed calls有一些特殊的方法,但它們不適用于協程。
總結
以上是生活随笔為你收集整理的python协程asyncio 应用_Python-如何使用asyncio同时运行多个协程?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言 | 内存对齐02 - 为什么会有
- 下一篇: python numpy和pandas数