apply_async()无法修改multiprocessing.Manager().list()多维列表的所有原因
时间: 2023-11-28 16:51:38 浏览: 89
async_fifo.v.rar_FIFO verilog_async fifo_async_fifo.v_fifo veri
`apply_async()`方法是异步执行函数的方法,因此它会在另一个进程中执行代码。由于多进程之间是不能直接共享内存的,因此在子进程中访问父进程的`Manager().list()`多维列表时,需要使用代理对象来进行访问。这个代理对象是由`Manager()`类提供的,它可以让多个进程共享一个对象。
然而,`apply_async()`方法中的函数会在子进程中执行,并且无法直接访问原始的多维列表对象。因此,如果尝试在子进程中修改`Manager().list()`多维列表对象,实际上会在代理对象中创建一个新的子列表对象,并将修改应用于该子列表对象。这意味着在子进程中所做的更改不会对原始的多维列表对象产生任何影响。
为了解决这个问题,可以使用`Manager().list()`多维列表的`get()`方法来获取代理对象的副本,然后在子进程中修改副本。完成修改后,可以使用`set()`方法将修改后的副本写回到代理对象中。这样做可以确保多进程之间共享的是同一个对象,而不是代理对象中的子列表对象。
示例代码如下:
```python
from multiprocessing import Pool, Manager
def func(l):
sub_l = l[0]
sub_l[0] = 1 # 在子进程中修改副本
l[0] = sub_l # 将修改后的副本写回到代理对象中
if __name__ == '__main__':
with Manager() as manager:
arr = manager.list([[0]])
pool = Pool()
pool.apply_async(func, args=(arr,))
pool.close()
pool.join()
print(arr) # 输出 [[1]]
```
在这个示例代码中,我们使用了`Manager().list()`多维列表来创建一个包含一个子列表的列表对象。在`func()`函数中,我们先获取代理对象的副本,然后在副本中修改了第一个元素。接着,我们将修改后的副本写回到代理对象中,确保多进程之间共享的是同一个对象。最后,我们在主进程中打印出代理对象中的值,验证了修改已经成功应用到原始的多维列表对象上。
阅读全文