我有一个声明为全局变量的空列表。我给它赋值。但是当我尝试做多处理池时,全局变量是空列表而不是赋值。
from multiprocessing import Process, Pool
camera_data = [{"id": "1", "url": "cam-c.jpg", "area": "1"},
{"id": "2", "url": "cam-d.jpg", "area": "1"},
{"id": "3", "url": "cam-e.jpg", "area": "2"},
{"id": "4", "url": "cam-f.jpg", "area": "2"}]
bulb_data = []
def framed_images(fake):
print(bulb_data)
if __name__ == '__main__':
print("camera_data - ",camera_data)
for data in camera_data:
bulb_data.append({"url": data["url"], "bulb": False})
print("bulb_data - ",bulb_data)
# framed_images()
fake_Data = bulb_data
with Pool(processes=4) as pool:
pool.map(framed_images, fake_Data)
我得到的输出为:
camera_data - [{'id': '1', 'url': 'cam-c.jpg', 'area': '1'}, {'id': '2', 'url': 'cam-d.jpg', 'area': '1'}, {'id': '3', 'url': 'cam-e.jpg', 'area': '2'}, {'id': '4', 'url': 'cam-f.jpg', 'area': '2'}]
bulb_data - [{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]
[]
[]
[]
[]
最后四个空列表来自多处理池。我期望输出如下:
[{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]
[{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]
[{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]
[{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]
以便在全局变量更新时编辑每个进程中的字典列表。
4条答案
按热度按时间i1icjdpr1#
这可能是因为您使用的是
spawn
启动方法,当使用该方法时,进程只会从产生它们的进程继承bear minimum。这是MacOS和Windows上的默认启动方法,也是Windows操作系统上唯一的启动方法。您可以在此处阅读有关不同启动方法的文档。
文档还指出了使用
spawn
或forkserver
启动方法时全局变量的这一点:请记住,如果在子进程中运行的代码试图访问全局变量,那么它看到的值(如果有的话)可能与调用Process.start时父进程中的值不同。然而,全局变量只是模块级常量,不会引起任何问题。
https://docs.python.org/3/library/multiprocessing.html?highlight=multiprocessing#the-spawn-and-forkserver-start-methods
niwlg2el2#
input参数(iterable)是强制性的,并且您希望通过framed_images中未使用的输入和导致该输出的全局列表的技巧来实现这一点。
其背后的原因是,多进程池为该功能创建子进程,并且将与块大小参数相关的自变量(这里是称为fake_Data的列表)划分为每个子进程,并且不存在共享存储器。
你可以像这样引用对象,但是我从来没有试过。https://docs.python.org/3/library/multiprocessing.html#shared-ctypes-objects
虽然,我认为你可以用一个使用共享内存的多线程模块来实现。尝试使用子进程不是你所需要的。
9jyewag03#
正如所指出的,在Windows(或Mac-OS,因为它们都使用X1 M0 N1 X)上,每个派生的“子”都有自己的单独内存,并导入您的脚本,因此它们基本上是这样做的。
如果你运行这段代码,你会得到一个空列表,在Linux上,它略有不同,你会得到你的“预期结果”,因为它使用
fork
,但内存仍然没有共享,任何修改其中之一不会影响其他进程。解决这个问题的方法是使用存在于其他进程中的托管列表,并涉及IPC以跨进程同步该列表。
注意,每次访问这个“共享列表”都涉及到IPC,它比普通列表慢,所以要尽量少用它,所以不要在里面放很多对象或大对象。共享状态文档
9o685dep4#
解决方案代码:
使用共享首选项和共享所有子进程的输出与主代码.因此我可以做任何我想要的结果