gpt4 book ai didi

python - 如何使 multiprocessing.Array 进程在 python 中安全

转载 作者:行者123 更新时间:2023-12-05 04:50:05 25 4
gpt4 key购买 nike

在构建multiprocessing.Array 时,构造函数采用参数lock。默认设置为 True

据我了解,当 lock 标志设置为 True 时,由此创建的 multiprocessing.Array 应该是进程安全的。但是,我无法验证该行为。

我正在使用以下代码片段来验证行为:

import multiprocessing
def withdraw(balance):
for _ in range(10000):
balance[0] = balance[0] - 1
def deposit(balance):
for _ in range(10000):
balance[0] = balance[0] + 1
balance = multiprocessing.Array('f',[1000],lock=True) ### Notice lock=True passed explicitly
p1 = multiprocessing.Process(target=withdraw, args=(balance,))
p2 = multiprocessing.Process(target=deposit, args=(balance,))
p1.start()
p2.start()
p1.join()
p2.join()
print("Final balance = {}".format(balance[0]))

由于竞争条件影响了运行,每次我运行这段代码时,我都会看到不同的最终结果。

你能帮我理解我在做什么和/或理解错误吗?根据我的理解,我发布的代码片段应该始终打印 1000

最佳答案

锁并不像你想象的那么原子。它只包装每个单独的读取或写入。我估计,在读取当前值和写入新值之间的间隙中,另一个进程已经跳入并保存了一个新值。保存此更改时,这些更改将被破坏。

有一个针对 Multiprocessing.Value 的说明这是有见地的...

Python 3.9 documentation

如果您将读取和写入都绑定(bind)到单个事务中,并使用描述的 get_lock(),它将满足您的期望...

def deposit(balance):
for _ in range(10000):
with balance.get_lock():
balance[0] = balance[0] + 1


def withdraw(balance):
for _ in range(10000):
with balance.get_lock():
balance[0] = balance[0] - 1

为了好玩和理解,您可以将 for 循环包裹在锁中,观察它按顺序执行 所有 提款,然后释放锁并执行 所有 因此按顺序存款:

def withdraw(balance):
with balance.get_lock():
for _ in range(1, 1001):
balance[0] = balance[0] - 1
sys.stdout.write(f'w {balance[0]}\n')

关于python - 如何使 multiprocessing.Array 进程在 python 中安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67378454/

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