我有一个json
文件,其中只有一个对象:
incme.json
:
{
"value": 0
}
我正在尝试使用multiprocessing
和ProcessPoolExecutor
更新它,并使用multiprocessing.Lock
防止竞争条件:
from concurrent.futures import ProcessPoolExecutor
import multiprocessing as mp
import numpy as np
import json
def inc(tup):
lock, ignoreme = tup
with lock:
with open('incme.json', 'r') as f:
data = json.load(f)
print (data)
data['value'] += 1
with lock:
with open('incme.json', 'w') as f:
json.dump(data, fp=f, indent=4)
ignoreme += 1
if __name__ == '__main__':
m = mp.Manager()
lock = m.Lock()
NUMBER_OF_CPUS = mp.cpu_count()
# use up to +++ of the cpu`s available
USE_UP_TO = 0.5
inc((lock, 1))
with ProcessPoolExecutor(max_workers=np.uint16(NUMBER_OF_CPUS * USE_UP_TO)) as executor:
for i in range(100):
print('inc:')
executor.submit(inc, ((lock, 1)))
当上面的代码运行时,它将使value
成为44
或低于101
的值
以这种方式使用锁时:
def inc(tup):
lock, ignoreme = tup
with lock:
with open('incme.json', 'r') as f:
data = json.load(f)
print (data)
data['value'] += 1
with open('incme.json', 'w') as f:
json.dump(data, fp=f, indent=4)
ignoreme += 1
value
变为101
,但现在它不异步工作。
这是什么原因造成的?它是否与IO相关的任务有关
您的锁似乎保护得太少。是的,您以原子方式读取,您以原子方式写入,但您不以原子方式执行读取增量写入序列。例如,没有什么可以阻止所有100个进程读取0,然后每个进程将1添加到0,然后每个进程将1作为新值写入
相反,请尝试删除第二个
with lock:
语句,并缩进print()
和increment语句,以便以原子方式完成整个读增量写序列编辑
哎呀!我知道你已经试过了,而且已经发现它有效了。所以我对你为什么认为原来的方式“应该”起作用感到困惑。显然不应该;-)
相关问题 更多 >
编程相关推荐