Asyncio与aiohttp使用中出现cvim_headers被覆盖的竞态问题
问题根因
- 你代码中
cvim_headers = self.constants.cvim_headers这行直接引用了全局常量存储的字典对象,Python中字典属于可变对象,此处赋值仅传递内存地址不会生成新副本,所有并发运行的cvim_vlan_list协程操作的都是同一个cvim_headers实例,你为X-Auth-token赋值时会互相覆盖,这就是token被意外改写的核心原因,和asyncio的协程调度逻辑结合后就出现了你观察到的竞态现象。
修复方案
只需要在每次初始化cvim_headers时做一次拷贝即可,将原代码:
cvim_headers = self.constants.cvim_headers
修改为:
# 浅拷贝,每个协程使用独立的headers对象 cvim_headers = self.constants.cvim_headers.copy()
如果你的cvim_headers内部存在嵌套的可变对象,改用深拷贝即可:
import copy cvim_headers = copy.deepcopy(self.constants.cvim_headers)
额外优化建议
- Python 3.7+推荐直接用
asyncio.run()托管事件循环生命周期,不需要手动创建、绑定事件循环,可规避手动管理event loop带来的潜在异常 - 你循环中累加的
x变量不存在延迟绑定问题,每次调用cvim_vlan_list传递的都是当前迭代的x值,无需额外调整 - 不需要手动为task绑定loop,直接用
asyncio.create_task()即可,默认会使用当前运行的事件循环实例
内容的提问来源于stack exchange,提问作者marhyno
相关产品推荐
相关产品推荐

