gpt4 book ai didi

python - 异步函数中的变量未在 while-True 循环中重新计算

转载 作者:太空宇宙 更新时间:2023-11-03 14:44:34 24 4
gpt4 key购买 nike

我制作了一个虚拟服务器来测试我的 websockets 应用程序。它监听订阅 消息,然后通过套接字提供有关这些订阅的信息。

类的 subscriptions 属性在初始化时为空,并且应该在 listen() 函数接收订阅消息时填充。然而,似乎 talk() 中的 self.subscriptions 从未被附加到,让它陷入无限的 while 循环并且永远不会传输消息。

通过在 for 循环之后添加一行 await asyncio.sleep(1) 解决了这个问题。但为什么? self.subscriptions 难道不应该在每次 for 循环开始时重新求值吗?

代码如下:

class DummyServer:
def __init__(self):
self.subscriptions = []

def start(self):
return websockets.serve(self.handle, 'localhost', 8765)

async def handle(self, websocket, path):
self.ws = websocket
listen_task = asyncio.ensure_future(self.listen())
talk_task = asyncio.ensure_future(self.talk())

done, pending = await asyncio.wait(
[listen_task, talk_task],
return_when=asyncio.FIRST_COMPLETED
)

for task in pending:
task.cancel()

async def listen(self):
while True:
try:
msg = await self.ws.recv()
msg = json.loads(msg)
await self.triage(msg) # handles subscriptions
except Exception as e:
await self.close()
break

async def talk(self):
while True:
for s in self.subscriptions:
dummy_data = {
'product_id': s
}
try:
await self.send(json.dumps(dummy_data))
except Exception as e:
await self.close()
break

await asyncio.sleep(1) # without this line, no message is ever sent

最佳答案

在您的函数开始时,subscriptions 为空,for 主体未被评估。因此,您的协程实际上与:

async def talk(self):
while True:
pass

while 循环不包含“上下文切换点”,这意味着 asyncio 事件循环基本上卡在那里,永远执行阻塞 while 循环。

添加 await sleep() 打破魔圈;甚至 await sleep(0) 也有帮助。

聪明的代码可能应该将 asyncio.Conditionself.subscriptions 结合使用,但这超出了您最初问题的范围。

关于python - 异步函数中的变量未在 while-True 循环中重新计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50746986/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com