[英]How to make a multiprocessing.Array process safe in python
在构造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的注释记录在案,这是有见地的......
如果您将读取和写入都绑定到单个事务中,并使用描述的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')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.