作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
假设我有一辆从某处接收消息的总线。每条消息都有target
和msg
,我想实现一个订阅机制,让其他协程可以订阅
到特定的target
subscriptions = {}
async def subscribe(target):
subscriptions[target]= wait_for_messages()
async def proc_msg(target,msg);
subscriptions[target].send(msg)
async def wait_for_messages():
while True:
asyncio.sleep(1)
async def subscribe(target)
async for msg in subscribe(target):
print(msg)
我的问题是关于 wait_for_messages
,即使 sleep 可以正常工作(代码仅供演示),我如何才能等待发送命令而不经常 sleep 和醒来?
最佳答案
订阅机制来自回调世界和asyncio.Future - 是从基于回调的世界到基于协程的世界的某种桥梁:有了它你可以等待发生的事情。在 msg 到来时使用 set_result
并为 Future 使用 await
以在协程中接收 msg。
例如:
import asyncio
from random import randint
from collections import defaultdict
from contextlib import suppress
# MSG SUBSCRIBE/SEND API:
_futures = defaultdict(asyncio.Future)
async def msg_for_target(target):
"""Await for this coroutine to recieve msg."""
return await _futures[target]
def send_msg(target, msg):
_futures[target].set_result(msg)
del _futures[target] # We would need new Future for future subscribers
# TEST:
async def random_sender():
"""Send random messages."""
i = 0
while True:
i += 1
await asyncio.sleep(0.5)
target = randint(0, 3)
msg = f'msg {i}'
print(f'Sending msg "{msg}" for target "{target}" ...')
send_msg(target, msg)
async def main():
task = asyncio.ensure_future(random_sender())
for target in (2, 0, 3, 1):
print(f'> Subscribed for target "{target}"')
msg = await msg_for_target(target)
print(f'> Recieved "{msg}"')
print()
# Cleanup, see https://stackoverflow.com/a/43810272/1113207
task.cancel()
with suppress(asyncio.CancelledError):
await task
if __name__ == '__main__':
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main())
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()
输出:
> Subscribed for target "2"
Sending msg "msg 1" for target "2" ...
> Recieved "msg 1"
> Subscribed for target "0"
Sending msg "msg 2" for target "3" ...
Sending msg "msg 3" for target "0" ...
> Recieved "msg 3"
> Subscribed for target "3"
Sending msg "msg 4" for target "2" ...
Sending msg "msg 5" for target "2" ...
Sending msg "msg 6" for target "2" ...
Sending msg "msg 7" for target "1" ...
Sending msg "msg 8" for target "3" ...
> Recieved "msg 8"
> Subscribed for target "1"
Sending msg "msg 9" for target "0" ...
Sending msg "msg 10" for target "0" ...
Sending msg "msg 11" for target "2" ...
Sending msg "msg 12" for target "2" ...
Sending msg "msg 13" for target "1" ...
> Recieved "msg 13"
关于python - 异步如何暂停协程直到调用发送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47750456/
在我的设置中,我试图有一个界面 Table继承自 Map (因为它主要用作 map 的包装器)。两个类继承自 Table - 本地和全局。全局的将有一个可变的映射,而本地的将有一个只有本地条目的映射。
Rust Nomicon 有 an entire section on variance除了关于 Box 的这一小节,我或多或少地理解了这一点和 Vec在 T 上(共同)变体. Box and Vec
我是一名优秀的程序员,十分优秀!