Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python aiohttp socketio中是否可能有竞争条件?_Python_Asynchronous_Race Condition_Aiohttp_Python Socketio - Fatal编程技术网

在python aiohttp socketio中是否可能有竞争条件?

在python aiohttp socketio中是否可能有竞争条件?,python,asynchronous,race-condition,aiohttp,python-socketio,Python,Asynchronous,Race Condition,Aiohttp,Python Socketio,我正在编写类似于下面代码的代码。有时程序停止工作,或者我在访问socketio会话时遇到奇怪的错误。慢慢地,我觉得这可能是比赛条件 它更多的是伪代码。我想演示一下,我从多个协同路由访问全局共享状态和socketio会话 这里肯定有个问题: for sid in app["sockets"]: # you are iterating over a list here await sio.save_session(...) # your coroutine will yield here

我正在编写类似于下面代码的代码。有时程序停止工作,或者我在访问socketio会话时遇到奇怪的错误。慢慢地,我觉得这可能是比赛条件

它更多的是伪代码。我想演示一下,我从多个协同路由访问全局共享状态和socketio会话


这里肯定有个问题:

for sid in app["sockets"]:  # you are iterating over a list here
    await sio.save_session(...)  # your coroutine will yield here
您正在迭代列表
app[“sockets”]
,并且在每次迭代中使用
wait
关键字。当使用
wait
关键字时,将支持您的协同程序,事件循环将检查是否可以执行或恢复另一个协同程序

假设
connect(…)
coroutine在
session\u路由
等待时运行

app["sockets"].append(sid)  # this changed the structure of the list
connect(…)
更改了列表的结构。此可以使该列表当前存在的所有迭代器无效。
disconnect(…)
coroutine也是如此

因此,要么不要修改列表,要么至少不要在列表更改后重用迭代器。后一种解决方案在这里更容易实现:

for sid in list(app["sockets"]):
    await sio.save_session(...)
现在for循环在原始列表的副本上迭代。现在更改列表不会“干扰”副本

但是请注意,副本无法识别列表中的添加和删除

因此,简而言之,您的问题的答案是,但它与异步io无关。同步代码中很容易出现同样的问题:

for i in my_list:
    my_list.remove(1)  # don't do this

另一个选项是使用
asyncio.Lock
保护套接字列表,以便套接字上的循环和套接字的添加和删除不能相互交织。所有添加和删除操作都将等待保存循环完成后进行。如果在列表中获得锁并移除该锁,那么您在最后指出的问题将导致死锁。
for i in my_list:
    my_list.remove(1)  # don't do this