python - 如何在这里避免竞争条件
问题描述
getUrl
如果我使用线程运行它会出现竞争条件吗?我正在更改data['key']
多个线程中的值。我需要将整个传递data
给我提出的请求,基本上,一组键将被固定,只有命名的键key
会因我进行的每个线程调用而改变
import requests
from concurrent.futures import ThreadPoolExecutor
def getUrl(url, value):
data['key'] = value # will there be a race condition here
return requests.get(url, data=data).text # and when the value is passed here
data = {'key': 1, 'fixedKey': 'fixedValue', 'fixedKey2': 'fixedValue2'}
resultArray = []
threadPool = ThreadPoolExecutor(32)
for i in range(100):
resultArray.append(threadPool.submit(getUrl, 'https://google.com', i))
Python字典中的线程安全我检查了这个,但我的困惑是当我进行设置时线程切换上下文data['key'] = value
,然后其他一些线程更改它并且下一行现在具有由不同线程设置的新值。
例子
Value set by thread 1
data['key'] = 1
Context Switch
Value set by thread 2
data['key'] = 2
Context Switch back to old thread 1
is data['key'] = `2` now? I would necessarily want the value `1`
如果我使用锁,那么我将在这里失去并发性。
解决方案
存在竞争条件,因为data
在线程之间共享并且您从它们中对其进行了变异。
可视化这种竞争条件的一种简单方法是使用 a和模拟request
调用:sleep
print
from concurrent.futures import ThreadPoolExecutor
from time import sleep
def getUrl(url, value):
data['key'] = value
sleep(0.3)
print(value, data["key"])
data = {'key': 1, 'fixedKey': 'fixedValue', 'fixedKey2': 'fixedValue2'}
resultArray = []
threadPool = ThreadPoolExecutor(32)
for i in range(100):
resultArray.append(threadPool.submit(getUrl, 'https://google.com', i))
您会看到传递给的值getUrl
有时与存储在data
.
data
一种解决方案是在对其进行变异之前在本地复制。
推荐阅读
- git - 删除在所有后续提交中合并和取消合并此功能的功能
- excel - 仅使用 VBA 删除某个条件格式规则
- javascript - 如何在 Google 表格的条件格式中使用 if 语句?
- mysql - 将 varchar 长度从 80 更改为 160,但在基本视图中它仍然显示为 80?
- r - kableExtra:如果一个表中包含多个数据帧,则 short.caption 参数不起作用
- c# - 'xscgen' 未被识别为内部或外部命令
- python - 数据框行项目到列
- python - 使用 np.where 函数时出现“无法使用长度与值不同的多索引选择索引器进行设置”错误
- c++ - 程序正在执行,但未打印正确的详细信息
- import - 防止动态猫头鹰:在 Jena OntModel 中导入