在您的示例中,同步缺少一点。manager.list只是一个普通的list,您的工作进程可以通过代理对象修改它。您的后续进程碰巧同时检查len(my_array)。在
没有同步,这告诉他们应该等到另一个进程完成了它的操作,包括执行这个长度检查,并根据这个检查的结果执行一个操作。更新操作不是原子操作,需要使用经理.lock你的行动。在
代码中还有另一个问题,即重新绑定my_array指向普通列表['y'],而不是更新/修改共享的manager.list。您不是用设置了my_array = ['y']的进程修改{},manager.list从第一次修改到第一个工作进程直到程序结束,它的值['a', 'b', 'c', 'x']。在from multiprocessing import Process, Manager
def f(my_array, lock):
with lock:
if len(my_array) < 4:
my_array.append('x')
else:
my_array[:] = [] # clear list inplace by assigning
# empty list to slice of manager.list
my_array.append('y')
print(my_array)
if __name__ == '__main__':
N_WORKERS = 5
with Manager() as manager:
my_array = manager.list(['a', 'b', 'c'])
lock = manager.Lock()
pool = [
Process(target=f, args=(my_array, lock)) for _ in range(N_WORKERS)
]
for p in pool:
p.start()
for p in pool:
p.join()
# Leaving the context-manager block will shut down the manager-process.
# We need to convert the manager-list to a normal list in the parent
# to keep its values available for further processing in the parent.
result = list(my_array)
print(f'result: {result}')
输出示例:
^{pr2}$